Compare commits
79 Commits
Author | SHA1 | Date |
---|---|---|
Jinhuan | a8d4a359c4 | 3 months ago |
Jinhuan | c10ad02d1a | 3 months ago |
Jinhuan | cc8ce53abc | 9 months ago |
seiyu | ca135833a0 | 10 months ago |
seiyu | b2cba2ee05 | 10 months ago |
seiyu | 096007f412 | 10 months ago |
seiyu | 1864c6cf04 | 10 months ago |
seiyu | c7c63a3b2e | 10 months ago |
seiyu | e376b84212 | 10 months ago |
Jeffrey_Li | 2506ac806e | 10 months ago |
Jeffrey_Li | 03444ed917 | 10 months ago |
seiyu | fc8f54c7d3 | 10 months ago |
seiyu | 215acc558b | 1 year ago |
seiyu | 39f080cdca | 1 year ago |
seiyu | 3f6c64d10c | 1 year ago |
Flamingo | 4c319c9ae5 | 1 year ago |
seiyu | 7d33939aa1 | 1 year ago |
Jeffrey_Li | 2020f6a810 | 1 year ago |
seiyu | 92d931e56d | 1 year ago |
seiyu | 9e2355e2d5 | 1 year ago |
Flamingo | 6dffbbba19 | 1 year ago |
seiyu | 5aa4f78df5 | 1 year ago |
seiyu | d5303e4de1 | 1 year ago |
Flamingo | f565de07a8 | 1 year ago |
seiyu | ed9c76f165 | 1 year ago |
seiyu | dfacffd891 | 1 year ago |
seiyu | a4a9b3f7e1 | 1 year ago |
seiyu | 79d7bb38c5 | 1 year ago |
seiyu | 9fc16465ed | 1 year ago |
Chu Jun | 805cdc855c | 1 year ago |
seiyu | 85d59b3ee9 | 1 year ago |
seiyu | 41fe0fff27 | 1 year ago |
seiyu | 637bbef357 | 1 year ago |
seiyu | 96e94011c4 | 1 year ago |
Jeffrey_Li | 6cc6ed3e76 | 1 year ago |
Jeffrey_Li | 4728a58767 | 1 year ago |
Jeffrey_Li | 3863c89610 | 1 year ago |
seiyu | f5be5614bf | 1 year ago |
Jeffrey_Li | 1ba73b82f2 | 1 year ago |
seiyu | b9d04918b9 | 1 year ago |
18661908385 | 4323f75315 | 1 year ago |
Jeffrey_Li | 1e9c49ec92 | 1 year ago |
Jeffrey_Li | 088f6fb1a0 | 1 year ago |
Jeffrey_Li | b6f0e95103 | 1 year ago |
Jeffrey_Li | 20165d19d2 | 1 year ago |
Jeffrey_Li | a6da5c3b77 | 1 year ago |
Jeffrey_Li | 228e781876 | 1 year ago |
Jeffrey_Li | 8720cce3d4 | 1 year ago |
Flamingo | fc94eea6ae | 1 year ago |
Flamingo | fc3e8de896 | 1 year ago |
CJ980606 | aa9e765f26 | 1 year ago |
18661908385 | e9233bd88c | 1 year ago |
Jeffrey_Li | 521d4d8c2f | 1 year ago |
Jeffrey_Li | f421a7ca7d | 2 years ago |
Jeffrey_Li | 5b66880fc9 | 2 years ago |
CJ980606 | ee453f2857 | 2 years ago |
Jeffrey_Li | a65d0b6006 | 2 years ago |
Jeffrey_Li | 02edff48f1 | 2 years ago |
Jeffrey_Li | e775e1a5b9 | 2 years ago |
Jeffrey_Li | e792799564 | 2 years ago |
CJ980606 | 1d1a359538 | 2 years ago |
CJ980606 | 3876b4db1c | 2 years ago |
CJ980606 | 3259939c6f | 2 years ago |
Jinhuan | 083f23904e | 2 years ago |
Jinhuan | a9a31c5f09 | 2 years ago |
chu270213 | ee80071d78 | 2 years ago |
chu270213 | a8ad96ba65 | 2 years ago |
chu270213 | 70ff5d9c5c | 2 years ago |
chu270213 | 2f4b992597 | 2 years ago |
18661908385 | 9ccb9da2dd | 2 years ago |
18661908385 | 263ec6e37e | 2 years ago |
18661908385 | 4f2ebf3e6b | 2 years ago |
18661908385 | 1f54c4f478 | 2 years ago |
chu270213 | f7b3dd9d52 | 2 years ago |
chu270213 | e5ff69058e | 2 years ago |
chu270213 | 3f210607cc | 2 years ago |
CJ980606 | aa83fbff41 | 2 years ago |
CJ980606 | d46335bc55 | 2 years ago |
chu270213 | 743374770c | 2 years ago |
@ -0,0 +1,343 @@
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
|
||||
runtime/
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
GeneratedFiles/
|
||||
model/
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
# StyleCop
|
||||
StyleCopReport.xml
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_h.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.iobj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding add-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/[Pp]ackages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/[Pp]ackages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/[Pp]ackages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
*.appx
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!?*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Including strong name files can present a security risk
|
||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||
#*.snk
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
# ASP.NET Core default setup: bower directory is configured as wwwroot/lib/ and bower restore is true
|
||||
**/wwwroot/lib/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
ServiceFabricBackup/
|
||||
*.rptproj.bak
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
*.rptproj.rsuser
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# JetBrains Rider
|
||||
.idea/
|
||||
*.sln.iml
|
||||
|
||||
# CodeRush personal settings
|
||||
.cr/personal
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
# tools/**
|
||||
# !tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
# OpenCover UI analysis results
|
||||
OpenCover/
|
||||
|
||||
# Azure Stream Analytics local run output
|
||||
ASALocalRun/
|
||||
|
||||
# MSBuild Binary and Structured Log
|
||||
*.binlog
|
||||
|
||||
# NVidia Nsight GPU debugger configuration file
|
||||
*.nvuser
|
||||
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
.mfractor/
|
||||
|
||||
# Local History for Visual Studio
|
||||
.localhistory/
|
||||
|
||||
# BeatPulse healthcheck temp database
|
||||
healthchecksdb
|
@ -0,0 +1,68 @@
|
||||
{
|
||||
"files.associations": {
|
||||
"string": "cpp",
|
||||
"array": "cpp",
|
||||
"atomic": "cpp",
|
||||
"bit": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"cctype": "cpp",
|
||||
"chrono": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"compare": "cpp",
|
||||
"complex": "cpp",
|
||||
"concepts": "cpp",
|
||||
"condition_variable": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"deque": "cpp",
|
||||
"list": "cpp",
|
||||
"map": "cpp",
|
||||
"set": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"vector": "cpp",
|
||||
"exception": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"functional": "cpp",
|
||||
"iterator": "cpp",
|
||||
"memory": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"numeric": "cpp",
|
||||
"random": "cpp",
|
||||
"ratio": "cpp",
|
||||
"string_view": "cpp",
|
||||
"system_error": "cpp",
|
||||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"fstream": "cpp",
|
||||
"future": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"iostream": "cpp",
|
||||
"istream": "cpp",
|
||||
"limits": "cpp",
|
||||
"mutex": "cpp",
|
||||
"new": "cpp",
|
||||
"numbers": "cpp",
|
||||
"ostream": "cpp",
|
||||
"semaphore": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"stop_token": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"thread": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"typeindex": "cpp",
|
||||
"typeinfo": "cpp"
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
/* This file was generated by qmake with the info from <root>/src/mqtt/mqtt.pro. */
|
||||
#ifdef __cplusplus /* create empty PCH in C mode */
|
||||
#include <QtCore/QtCore>
|
||||
#include <QtNetwork/QtNetwork>
|
||||
#endif
|
Binary file not shown.
Binary file not shown.
@ -0,0 +1,3 @@
|
||||
#include "ASyncQueue.h"
|
||||
|
||||
|
@ -0,0 +1,81 @@
|
||||
#pragma once
|
||||
#include<mutex>
|
||||
//#include<condition_variable>
|
||||
#include<list>
|
||||
#include<iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
template<class T> class ASyncQueue
|
||||
{
|
||||
public:
|
||||
ASyncQueue(int max_size);
|
||||
~ASyncQueue();
|
||||
void put(const T& val);
|
||||
void take(T& val);
|
||||
void clear();
|
||||
bool isEmpty();
|
||||
bool isFull();
|
||||
int count();
|
||||
public:
|
||||
string name;
|
||||
private:
|
||||
mutex lock;
|
||||
//condition_variable_any cv_full, cv_empty;
|
||||
list<T> q;
|
||||
int size;
|
||||
int max_size;
|
||||
};
|
||||
|
||||
using namespace std;
|
||||
|
||||
template<class T>
|
||||
ASyncQueue<T>::ASyncQueue(int max_size) :max_size(max_size)
|
||||
{
|
||||
}
|
||||
|
||||
template<class T>
|
||||
ASyncQueue<T>::~ASyncQueue()
|
||||
{
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void ASyncQueue<T>::put(const T& val)
|
||||
{
|
||||
lock_guard<mutex> locker(lock);
|
||||
q.emplace_back(val);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void ASyncQueue<T>::take(T& val)
|
||||
{
|
||||
lock_guard<mutex> locker(lock);
|
||||
val = q.front();
|
||||
q.pop_front();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void ASyncQueue<T>::clear()
|
||||
{
|
||||
lock_guard<mutex> locker(lock);
|
||||
q.clear();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool ASyncQueue<T>::isEmpty()
|
||||
{
|
||||
return q.size() == 0;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool ASyncQueue<T>::isFull()
|
||||
{
|
||||
return q.size() == max_size;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
int ASyncQueue<T>::count()
|
||||
{
|
||||
lock_guard<mutex> locker(lock);
|
||||
return q.size();
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
#include "AlarmInfo.h"
|
||||
|
||||
AlarmInfo::AlarmInfo()
|
||||
{
|
||||
}
|
||||
|
||||
AlarmInfo::~AlarmInfo()
|
||||
{
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
#include <iostream>
|
||||
class AlarmInfo
|
||||
{
|
||||
public:
|
||||
AlarmInfo();
|
||||
~AlarmInfo();
|
||||
|
||||
public:
|
||||
std::string alarm_start; //报警发生时间
|
||||
std::string alarm_handle; //报警处理时间
|
||||
std::string alarm_msg; //报警信息
|
||||
int alarm_code; //报警代码
|
||||
};
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,306 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;cxx;c;def</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Form Files">
|
||||
<UniqueIdentifier>{99349809-55BA-4b9d-BF79-8FDBB0286EB3}</UniqueIdentifier>
|
||||
<Extensions>ui</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}</UniqueIdentifier>
|
||||
<Extensions>qrc;*</Extensions>
|
||||
<ParseFiles>false</ParseFiles>
|
||||
</Filter>
|
||||
<Filter Include="Generated Files">
|
||||
<UniqueIdentifier>{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}</UniqueIdentifier>
|
||||
<Extensions>moc;h;cpp</Extensions>
|
||||
<SourceControlFiles>False</SourceControlFiles>
|
||||
</Filter>
|
||||
<Filter Include="Generated Files\Debug">
|
||||
<UniqueIdentifier>{21a337b6-7c4c-4375-86e6-fb668dce746e}</UniqueIdentifier>
|
||||
<Extensions>cpp;moc</Extensions>
|
||||
<SourceControlFiles>False</SourceControlFiles>
|
||||
</Filter>
|
||||
<Filter Include="Generated Files\Release">
|
||||
<UniqueIdentifier>{65773ffc-5f94-4329-b62b-afc0b9e58efa}</UniqueIdentifier>
|
||||
<Extensions>cpp;moc</Extensions>
|
||||
<SourceControlFiles>False</SourceControlFiles>
|
||||
</Filter>
|
||||
<Filter Include="Header Files\Ui">
|
||||
<UniqueIdentifier>{473883a5-266b-4c0a-97ce-c07ce50ee349}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header Files\Thread">
|
||||
<UniqueIdentifier>{081898e5-fc92-47a4-9de7-0317588c2c6c}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\Ui">
|
||||
<UniqueIdentifier>{045acf89-3551-4318-a690-0f58eaf08f4d}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\Thread">
|
||||
<UniqueIdentifier>{91e6e8fc-6df2-4732-839b-4f873694fc78}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="cigarette.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="basecamera.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SyncQueue.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="alg_jd.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="balluffcamera.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="plc_item.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="db_label.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="AlarmInfo.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="common.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ASyncQueue.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="baslercamera.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="hikcamera.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PLC\PLCDevice.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="exportData.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="tinyxml2.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Thread\CaptureThread.cpp">
|
||||
<Filter>Source Files\Thread</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Thread\CaptureThreadBasler.cpp">
|
||||
<Filter>Source Files\Thread</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Thread\CaptureThreadHIK.cpp">
|
||||
<Filter>Source Files\Thread</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Thread\Cleanthread.cpp">
|
||||
<Filter>Source Files\Thread</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Thread\debugthread.cpp">
|
||||
<Filter>Source Files\Thread</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Thread\Logthread.cpp">
|
||||
<Filter>Source Files\Thread</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Thread\syncworkthread.cpp">
|
||||
<Filter>Source Files\Thread</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Thread\threadReceive.cpp">
|
||||
<Filter>Source Files\Thread</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Thread\threadSend.cpp">
|
||||
<Filter>Source Files\Thread</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Thread\threadSendTCP.cpp">
|
||||
<Filter>Source Files\Thread</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Thread\workthread.cpp">
|
||||
<Filter>Source Files\Thread</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Ui\alarmdialog.cpp">
|
||||
<Filter>Source Files\Ui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Ui\camera_glue.cpp">
|
||||
<Filter>Source Files\Ui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Ui\change_shift.cpp">
|
||||
<Filter>Source Files\Ui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Ui\dialogin.cpp">
|
||||
<Filter>Source Files\Ui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Ui\dialogsetup.cpp">
|
||||
<Filter>Source Files\Ui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Ui\dialogsetuppasswd.cpp">
|
||||
<Filter>Source Files\Ui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Ui\output_statistic.cpp">
|
||||
<Filter>Source Files\Ui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Ui\plcsetup.cpp">
|
||||
<Filter>Source Files\Ui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Thread\threadSendMqtt.cpp">
|
||||
<Filter>Source Files\Thread</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtMoc Include="cigarette.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</QtMoc>
|
||||
<QtUic Include="cigarette.ui">
|
||||
<Filter>Form Files</Filter>
|
||||
</QtUic>
|
||||
<QtRcc Include="cigarette.qrc">
|
||||
<Filter>Resource Files</Filter>
|
||||
</QtRcc>
|
||||
<QtMoc Include="db_label.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="exportData.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Thread\CaptureThread.h">
|
||||
<Filter>Header Files\Thread</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Thread\CaptureThreadBasler.h">
|
||||
<Filter>Header Files\Thread</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Thread\CaptureThreadHIK.h">
|
||||
<Filter>Header Files\Thread</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Thread\Cleanthread.h">
|
||||
<Filter>Header Files\Thread</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Thread\debugthread.h">
|
||||
<Filter>Header Files\Thread</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Thread\Logthread.h">
|
||||
<Filter>Header Files\Thread</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Thread\savethread.h">
|
||||
<Filter>Header Files\Thread</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Thread\syncworkthread.h">
|
||||
<Filter>Header Files\Thread</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Thread\threadReceive.h">
|
||||
<Filter>Header Files\Thread</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Thread\workthread.h">
|
||||
<Filter>Header Files\Thread</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Ui\alarmdialog.hpp">
|
||||
<Filter>Header Files\Ui</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Ui\dialogin.hpp">
|
||||
<Filter>Header Files\Ui</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Ui\dialogsetup.hpp">
|
||||
<Filter>Header Files\Ui</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Ui\dialogsetuppasswd.hpp">
|
||||
<Filter>Header Files\Ui</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Ui\plcsetup.hpp">
|
||||
<Filter>Header Files\Ui</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Ui\camera_glue.h">
|
||||
<Filter>Header Files\Ui</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Ui\change_shift.h">
|
||||
<Filter>Header Files\Ui</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Ui\output_statistic.h">
|
||||
<Filter>Header Files\Ui</Filter>
|
||||
</QtMoc>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="basecamera.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="SyncQueue.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="alg_jd.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="balluffcamera.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="common.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="plc_item.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="AlarmInfo.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ASyncQueue.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="baslercamera.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="hikcamera.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PLC\PLCDevice.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="tinyxml2.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FtpManager.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Thread\threadSend.h">
|
||||
<Filter>Header Files\Thread</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Thread\threadSendTCP.h">
|
||||
<Filter>Header Files\Thread</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Thread\threadSendMqtt.h">
|
||||
<Filter>Header Files\Thread</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtUic Include="Ui\alarmdialog.ui">
|
||||
<Filter>Form Files</Filter>
|
||||
</QtUic>
|
||||
<QtUic Include="Ui\camera_glue.ui">
|
||||
<Filter>Form Files</Filter>
|
||||
</QtUic>
|
||||
<QtUic Include="Ui\change_shift.ui">
|
||||
<Filter>Form Files</Filter>
|
||||
</QtUic>
|
||||
<QtUic Include="Ui\dialogin.ui">
|
||||
<Filter>Form Files</Filter>
|
||||
</QtUic>
|
||||
<QtUic Include="Ui\dialogsetup.ui">
|
||||
<Filter>Form Files</Filter>
|
||||
</QtUic>
|
||||
<QtUic Include="Ui\dialogsetuppasswd.ui">
|
||||
<Filter>Form Files</Filter>
|
||||
</QtUic>
|
||||
<QtUic Include="Ui\output_statistic.ui">
|
||||
<Filter>Form Files</Filter>
|
||||
</QtUic>
|
||||
<QtUic Include="Ui\plcsetup.ui">
|
||||
<Filter>Form Files</Filter>
|
||||
</QtUic>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
<LocalDebuggerEnvironment>PATH=$(QTDIR)\bin%3b$(SOLUTIONDIR)runtime%3b$(QTDIR)\bin%3bD:\Qt\5.15.0\msvc2019_64\bin%3b$(PATH)</LocalDebuggerEnvironment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LocalDebuggerEnvironment>PATH=$(QTDIR)\bin%3bD:\Qt\5.15.2\msvc2019_64\bin%3b$(PATH)</LocalDebuggerEnvironment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<QtLastBackgroundBuild>2024-10-04T06:46:34.3746998Z</QtLastBackgroundBuild>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<QtLastBackgroundBuild>2024-10-04T06:46:35.5916473Z</QtLastBackgroundBuild>
|
||||
</PropertyGroup>
|
||||
</Project>
|
@ -0,0 +1,27 @@
|
||||
#include "CommonGUIFunctions.h"
|
||||
|
||||
#include "wxIncludePrologue.h"
|
||||
#include <wx/progdlg.h>
|
||||
#include "wxIncludeEpilogue.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void UpdateDeviceListWithProgressMessage( wxWindow* pParent, const mvIMPACT::acquire::DeviceManager& devMgr )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
static const int MAX_TIME_MS = 10000;
|
||||
wxProgressDialog progressDialog( wxT( "Scanning For Drivers, Interfaces and Devices" ),
|
||||
wxT( "Scanning for drivers, interfaces and devices...\n\nThis dialog will disappear automatically once this operation completes!" ),
|
||||
MAX_TIME_MS, // range
|
||||
pParent,
|
||||
wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_ELAPSED_TIME );
|
||||
UpdateDeviceListThread thread( devMgr );
|
||||
thread.Create();
|
||||
thread.Run();
|
||||
while( thread.IsRunning() )
|
||||
{
|
||||
wxMilliSleep( 100 );
|
||||
progressDialog.Pulse();
|
||||
}
|
||||
thread.Wait();
|
||||
progressDialog.Update( MAX_TIME_MS );
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef CommonGUIFunctionsH
|
||||
#define CommonGUIFunctionsH CommonGUIFunctionsH
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <mvIMPACT_CPP/mvIMPACT_acquire.h>
|
||||
|
||||
#include "wxIncludePrologue.h"
|
||||
#include <wx/thread.h>
|
||||
#include "wxIncludeEpilogue.h"
|
||||
|
||||
class wxWindow;
|
||||
|
||||
//=============================================================================
|
||||
//================= Implementation UpdateDeviceListThread =====================
|
||||
//=============================================================================
|
||||
//------------------------------------------------------------------------------
|
||||
class UpdateDeviceListThread : public wxThread
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
const mvIMPACT::acquire::DeviceManager& devMgr_;
|
||||
protected:
|
||||
void* Entry( void )
|
||||
{
|
||||
devMgr_.updateDeviceList();
|
||||
return 0;
|
||||
}
|
||||
public:
|
||||
explicit UpdateDeviceListThread( const mvIMPACT::acquire::DeviceManager& devMgr ) : wxThread( wxTHREAD_JOINABLE ),
|
||||
devMgr_( devMgr ) {}
|
||||
};
|
||||
|
||||
void UpdateDeviceListWithProgressMessage( wxWindow* pParent, const mvIMPACT::acquire::DeviceManager& devMgr );
|
||||
|
||||
#endif // CommonGUIFunctionsH
|
@ -0,0 +1,12 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef InfoH
|
||||
#define InfoH InfoH
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#define COMPANY_NAME wxT("MATRIX VISION GmbH")
|
||||
#define COMPANY_WEBSITE wxT("www.matrix-vision.com")
|
||||
#define COMPANY_SUPPORT_MAIL wxT("mailto:support@matrix-vision.com")
|
||||
#define CURRENT_YEAR wxT("2020")
|
||||
#define VERSION_STRING wxT("2.39.0.2982")
|
||||
|
||||
#endif // InfoH
|
@ -0,0 +1,22 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef ProxyResolverContextH
|
||||
#define ProxyResolverContextH ProxyResolverContextH
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <string>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class ProxyResolverContext
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
struct ProxyResolverContextImpl* pImpl_;
|
||||
public:
|
||||
explicit ProxyResolverContext( const std::wstring& userAgent = std::wstring(), const std::wstring& url = std::wstring() );
|
||||
~ProxyResolverContext();
|
||||
|
||||
std::wstring GetProxy( unsigned int index ) const;
|
||||
unsigned int GetProxyPort( unsigned int index ) const;
|
||||
};
|
||||
|
||||
bool IsCurrentUserLocalAdministrator( void );
|
||||
|
||||
#endif // ProxyResolverContextH
|
@ -0,0 +1,39 @@
|
||||
//----------------------------------------------------------------------------------------
|
||||
#ifndef aviexceptionH
|
||||
#define aviexceptionH aviexceptionH
|
||||
//----------------------------------------------------------------------------------------
|
||||
#include <string>
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
class AVIException
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
public:
|
||||
virtual const char* what() const = 0;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
class AEUnsupportedCodec : public AVIException
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
public:
|
||||
const char* what() const
|
||||
{
|
||||
return "Unsupported codec";
|
||||
}
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
class AVIWrapperException : public AVIException
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
std::string m_errorString;
|
||||
public:
|
||||
AVIWrapperException( const char* pError ) : m_errorString( pError ) {}
|
||||
const char* what() const
|
||||
{
|
||||
return m_errorString.c_str();
|
||||
}
|
||||
};
|
||||
|
||||
#endif // aviexceptionH
|
@ -0,0 +1,173 @@
|
||||
//----------------------------------------------------------------------------------------
|
||||
#include "avihelper.h"
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
using namespace std;
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
/*!
|
||||
\brief Builds an error string from an AVI error code.
|
||||
\param error The error code to be converted.
|
||||
|
||||
Helper function to convert an AVI error code into a string.
|
||||
*/
|
||||
string AVIErrorToString( HRESULT error )
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
string errormsg( "AVI error '" );
|
||||
switch( error )
|
||||
{
|
||||
case AVIERR_BADFLAGS :
|
||||
errormsg.append( "AVIERR_BADFLAGS" );
|
||||
break;
|
||||
case AVIERR_BADFORMAT :
|
||||
errormsg.append( "AVIERR_BADFORMAT" );
|
||||
break;
|
||||
case AVIERR_BADHANDLE :
|
||||
errormsg.append( "AVIERR_BADHANDLE" );
|
||||
break;
|
||||
case AVIERR_BADPARAM :
|
||||
errormsg.append( "AVIERR_BADPARAM" );
|
||||
break;
|
||||
case AVIERR_BADSIZE :
|
||||
errormsg.append( "AVIERR_BADSIZE" );
|
||||
break;
|
||||
case AVIERR_BUFFERTOOSMALL :
|
||||
errormsg.append( "AVIERR_BUFFERTOOSMALL" );
|
||||
break;
|
||||
case AVIERR_CANTCOMPRESS :
|
||||
errormsg.append( "AVIERR_CANTCOMPRESS" );
|
||||
break;
|
||||
case AVIERR_COMPRESSOR :
|
||||
errormsg.append( "AVIERR_COMPRESSOR" );
|
||||
break;
|
||||
case AVIERR_NOCOMPRESSOR :
|
||||
errormsg.append( "AVIERR_NOCOMPRESSOR" );
|
||||
break;
|
||||
case AVIERR_NODATA :
|
||||
errormsg.append( "AVIERR_NODATA" );
|
||||
break;
|
||||
case AVIERR_FILEOPEN :
|
||||
errormsg.append( "AVIERR_FILEOPEN" );
|
||||
break;
|
||||
case AVIERR_FILEREAD :
|
||||
errormsg.append( "AVIERR_FILEREAD" );
|
||||
break;
|
||||
case AVIERR_FILEWRITE :
|
||||
errormsg.append( "AVIERR_FILEWRITE" );
|
||||
break;
|
||||
case AVIERR_INTERNAL :
|
||||
errormsg.append( "AVIERR_INTERNAL" );
|
||||
break;
|
||||
case AVIERR_MEMORY :
|
||||
errormsg.append( "AVIERR_MEMORY" );
|
||||
break;
|
||||
case AVIERR_READONLY :
|
||||
errormsg.append( "AVIERR_READONLY" );
|
||||
break;
|
||||
case AVIERR_UNSUPPORTED :
|
||||
errormsg.append( "AVIERR_UNSUPPORTED" );
|
||||
break;
|
||||
case AVIERR_USERABORT :
|
||||
errormsg.append( "AVIERR_USERABORT" );
|
||||
break;
|
||||
case REGDB_E_CLASSNOTREG :
|
||||
errormsg.append( "REGDB_E_CLASSNOTREG" );
|
||||
break;
|
||||
default:
|
||||
return "Unrecognized error";
|
||||
}
|
||||
return( errormsg.append( "' occurred" ) );
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
/*!
|
||||
\brief Builds a test image.
|
||||
\param pData Pointer to the memory in which to build the test image.
|
||||
\param width The width of the test image.
|
||||
\param height The height of the test image.
|
||||
\param bytespp The bytes per pixel of the test image.
|
||||
|
||||
This function is only needed for testing purposes. It builds a moving vertical
|
||||
grey ramp in the memory pointed to by \e pData. In each new image will move one
|
||||
pixel to the right in order to simulate movement.
|
||||
*/
|
||||
void BuildTestImage( unsigned char* pData, int width, int height, int bytespp )
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
static int count = 0;
|
||||
unsigned char* p = pData;
|
||||
|
||||
for( int i = 0; i < height; i++ )
|
||||
{
|
||||
for( int j = 0; j < width; j++ )
|
||||
{
|
||||
for( int x = 0; x < bytespp; x++ )
|
||||
{
|
||||
p[x] = static_cast<unsigned char>( j + count % 256 );
|
||||
}
|
||||
p += bytespp;
|
||||
}
|
||||
}
|
||||
++count;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
/*!
|
||||
\brief Convertes a user selected codec into the corresponding 4 character code
|
||||
\param codec The codec to be converted.
|
||||
*/
|
||||
DWORD CodecToFourccCode( CODEC_T codec )
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
switch( codec )
|
||||
{
|
||||
case codecNoCompression:
|
||||
return mmioFOURCC( 'D', 'I', 'B', ' ' );
|
||||
case codecMorganMjpg:
|
||||
return mmioFOURCC( 'M', 'J', 'P', 'G' );
|
||||
case codecMorganMjpg2000:
|
||||
return mmioFOURCC( 'M', 'J', '2', 'C' );
|
||||
case codecIntelJpg:
|
||||
return mmioFOURCC( 'M', 'J', 'P', 'G' );
|
||||
case codecHuffYUV:
|
||||
return mmioFOURCC( 'H', 'F', 'Y', 'U' );
|
||||
case codecDivx5:
|
||||
return mmioFOURCC( 'd', 'i', 'v', 'x' );
|
||||
case codec3ivx:
|
||||
return mmioFOURCC( '3', 'i', 'v', '2' );
|
||||
case codecMjpg2:
|
||||
return mmioFOURCC( 'e', 'm', '2', 'v' );
|
||||
case codecPicVideoWavelet:
|
||||
return mmioFOURCC( 'p', 'v', 'w', '2' );
|
||||
case codecPicVideoMjpg:
|
||||
return mmioFOURCC( 'm', 'j', 'p', 'x' );
|
||||
case codecPicVideoLossLessJpg:
|
||||
return mmioFOURCC( 'p', 'i', 'm', 'j' );
|
||||
case codecMSVideo:
|
||||
return mmioFOURCC( 'm', 's', 'v', 'c' );
|
||||
case codecMSRle:
|
||||
return mmioFOURCC( 'm', 'r', 'l', 'e' );
|
||||
case codecMSH263:
|
||||
return mmioFOURCC( 'm', '2', '6', '3' );
|
||||
case codecMSH261:
|
||||
return mmioFOURCC( 'm', '2', '6', '1' );
|
||||
case codecIntelVidR32:
|
||||
return mmioFOURCC( 'i', 'v', '3', '2' );
|
||||
case codecIntelIndeo510:
|
||||
return mmioFOURCC( 'i', 'v', '5', '0' );
|
||||
case codecDivxMjpg4lm:
|
||||
return mmioFOURCC( 'd', 'i', 'v', '3' );
|
||||
case codecDivxMjpg4fm:
|
||||
return mmioFOURCC( 'd', 'i', 'v', '4' );
|
||||
case codecCinepack:
|
||||
return mmioFOURCC( 'c', 'v', 'i', 'd' );
|
||||
case codecMSMpeg4:
|
||||
return mmioFOURCC( 'm', 'p', 'g', '4' );
|
||||
case codecMax:
|
||||
return mmioFOURCC( 'D', 'I', 'B', ' ' );
|
||||
default:
|
||||
break;
|
||||
}
|
||||
throw AEUnsupportedCodec();
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
//----------------------------------------------------------------------------------------
|
||||
#ifndef avihelperH
|
||||
#define avihelperH avihelperH
|
||||
//----------------------------------------------------------------------------------------
|
||||
#include <windows.h>
|
||||
#include <Vfw.h>
|
||||
#include "aviexception.h"
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\brief The codecs recognized by the \b AVIWrapper class.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
codecNoCompression = 0,
|
||||
codecMorganMjpg = 1,
|
||||
codecMorganMjpg2000 = 2,
|
||||
codecIntelJpg = 3,
|
||||
codecHuffYUV = 4,
|
||||
codecDivx5 = 5,
|
||||
codec3ivx = 6,
|
||||
codecMjpg2 = 7,
|
||||
codecPicVideoWavelet = 8,
|
||||
codecPicVideoMjpg = 9,
|
||||
codecPicVideoLossLessJpg = 10,
|
||||
codecMSVideo = 11,
|
||||
codecMSRle = 12,
|
||||
codecMSH263 = 13,
|
||||
codecMSH261 = 14,
|
||||
codecIntelVidR32 = 15,
|
||||
codecIntelIndeo510 = 16,
|
||||
codecDivxMjpg4lm = 17,
|
||||
codecDivxMjpg4fm = 18,
|
||||
codecCinepack = 19,
|
||||
codecMSMpeg4 = 20,
|
||||
codecMax
|
||||
} CODEC_T;
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
std::string AVIErrorToString( HRESULT error );
|
||||
void BuildTestImage( unsigned char* pData, int width, int height, int bytespp );
|
||||
DWORD CodecToFourccCode( CODEC_T codec );
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
#endif // avihelperH
|
@ -0,0 +1,293 @@
|
||||
//----------------------------------------------------------------------------------------
|
||||
#include "aviwrapper.h"
|
||||
#include <cassert>
|
||||
#include <common/crt/mvstring.h>
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\class AVIWrapper
|
||||
\brief Provides an easy way to create and use *.avi-files.
|
||||
|
||||
This class is meant to provide easy access to the AVI file functions. It can be used to generate
|
||||
an AVI stream with only a few lines of code.
|
||||
|
||||
Three general methods are supported:
|
||||
|
||||
- Creation of an AVI stream using the standard Windows compression options dialog (interactively)
|
||||
- Creation of an AVI stream specifying a codec handler, quality settings and image dimensions
|
||||
(not interactively)
|
||||
- Creation of an AVI stream from images which are already in jpeg format.
|
||||
*/
|
||||
|
||||
unsigned int AVIWrapper::m_usageCount = 0;
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
/*!
|
||||
\brief Constructs a new \b AVIWrapper object.
|
||||
\param filename The filename of the AVI file to be created or \e 0 if no file shall be
|
||||
created.
|
||||
\param mode The access mode for this file.
|
||||
|
||||
Opens and creates an AVI file in the mode specified by the \e mode parameter if
|
||||
a filename has been specified. See MSDN for details about the available modes.
|
||||
*/
|
||||
AVIWrapper::AVIWrapper( const char* pFilename /* = 0 */, UINT mode /* = OF_READ */ ) :
|
||||
m_AVIStreamFrameCounter( 0 ), m_pAVIFile( 0 ), m_pAVIStream( 0 ), m_pAVIStreamCompressed( 0 ),
|
||||
m_codec( CodecToFourccCode( codecNoCompression ) )
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if( m_usageCount == 0 )
|
||||
{
|
||||
AVIFileInit();
|
||||
}
|
||||
++m_usageCount;
|
||||
if( pFilename )
|
||||
{
|
||||
HRESULT result = AVIFileOpen( &m_pAVIFile, pFilename, mode, 0 );
|
||||
if( result == AVIERR_OK )
|
||||
{
|
||||
result = AVIFileGetStream( m_pAVIFile, &m_pAVIStream, streamtypeVIDEO, 0 );
|
||||
}
|
||||
if( result != AVIERR_OK )
|
||||
{
|
||||
AVIFileExit();
|
||||
throw AVIWrapperException( AVIErrorToString( result ).c_str() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
AVIWrapper::~AVIWrapper( void )
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if( m_pAVIFile )
|
||||
{
|
||||
CloseStreamsAndFiles();
|
||||
}
|
||||
--m_usageCount;
|
||||
if( m_usageCount == 0 )
|
||||
{
|
||||
AVIFileExit();
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
/*!
|
||||
\brief Closes the AVI file again.
|
||||
|
||||
Closes all open streams and the AVI file itself. At the moment only one stream can be opened
|
||||
at the same time.
|
||||
*/
|
||||
void AVIWrapper::CloseAVIFile( void )
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if( !m_pAVIFile )
|
||||
{
|
||||
throw AVIWrapperException( "CloseAVIFile: No file has been opened so far" );
|
||||
}
|
||||
CloseStreamsAndFiles();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
/*!
|
||||
\brief Closes all open stream and the AVI file itself.
|
||||
*/
|
||||
void AVIWrapper::CloseStreamsAndFiles( void )
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if( m_pAVIStream )
|
||||
{
|
||||
AVIStreamRelease( m_pAVIStream );
|
||||
}
|
||||
if( m_pAVIStreamCompressed )
|
||||
{
|
||||
AVIStreamRelease( m_pAVIStreamCompressed );
|
||||
}
|
||||
if( m_pAVIFile )
|
||||
{
|
||||
AVIFileRelease( m_pAVIFile );
|
||||
}
|
||||
m_pAVIStream = 0;
|
||||
m_pAVIStreamCompressed = 0;
|
||||
m_pAVIFile = 0;
|
||||
m_AVIStreamFrameCounter = 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
/*!
|
||||
\brief Creates an AVI stream from DIB images.
|
||||
\param w The width of the images to be stored in the stream
|
||||
\param h The height of the images to be stored in the stream
|
||||
\param sampleRate The frames per second entry in the AVI header
|
||||
\param quality The JPEG quality (from 0 - 10000)
|
||||
\param name The name of the stream in the file
|
||||
\param codec The codec to be used for the compression of the DIB data. Pass \e codecMax if
|
||||
you want to select a codec from the standard Windows compression dialog or
|
||||
a valid codec from the \b CODEC_T enumeration.
|
||||
|
||||
Use this function to create a compressed or uncompressed AVI stream from images in DIB/Bitmap
|
||||
format. The images can be stored in a compressed format defined by the specified compression
|
||||
handler.
|
||||
|
||||
If your images are already in JPEG format use the function <b>AVIWrapper::CreateAVIStreamFromJPEGs()</b>
|
||||
instead.
|
||||
*/
|
||||
void AVIWrapper::CreateAVIStreamFromDIBs( int w, int h, int bitcount, DWORD sampleRate, DWORD quality, const char* pName /*= "default"*/, CODEC_T codec /*= codecMax*/ )
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
BITMAPINFOHEADER BmpHeader;
|
||||
SetupStreamStructs( BmpHeader, w, h, bitcount, sampleRate, quality, pName, codec );
|
||||
BmpHeader.biCompression = BI_RGB;
|
||||
AVICOMPRESSOPTIONS* opts[1] = {&m_AVICompressionOptions};
|
||||
memset( &m_AVICompressionOptions, 0, sizeof( AVICOMPRESSOPTIONS ) );
|
||||
PAVISTREAM streams[1] = {m_pAVIStream};
|
||||
|
||||
if( codec == codecMax )
|
||||
{
|
||||
// show windows compression handler dialog
|
||||
AVISaveOptions( 0, 0, 1, ( PAVISTREAM* )&streams, ( LPAVICOMPRESSOPTIONS* )&opts );
|
||||
}
|
||||
else // fill AVICOMPRESSOPTIONS with user parameters
|
||||
{
|
||||
m_codec = codec;
|
||||
opts[0]->fccType = streamtypeVIDEO;
|
||||
opts[0]->fccHandler = CodecToFourccCode( codec );
|
||||
opts[0]->dwQuality = quality;
|
||||
opts[0]->dwFlags = AVICOMPRESSF_VALID;
|
||||
}
|
||||
m_codec = opts[0]->fccHandler;
|
||||
HRESULT result = AVIMakeCompressedStream( &m_pAVIStreamCompressed, m_pAVIStream, &m_AVICompressionOptions, NULL );
|
||||
if( result == AVIERR_OK )
|
||||
{
|
||||
result = AVIStreamSetFormat( m_pAVIStreamCompressed, 0, &BmpHeader, sizeof( BITMAPINFOHEADER ) );
|
||||
}
|
||||
if( result != AVIERR_OK )
|
||||
{
|
||||
CloseStreamsAndFiles();
|
||||
throw AVIWrapperException( AVIErrorToString( result ).c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
/*!
|
||||
\brief Creates an AVI stream from JPEG images.
|
||||
\param w The width of the images to be stored in the stream
|
||||
\param h The height of the images to be stored in the stream
|
||||
\param sampleRate The frames per second entry in the AVI header
|
||||
\param quality The JPEG quality (from 0 - 10000)
|
||||
\param name The name of the stream in the file
|
||||
|
||||
Use this function to create a MJPEG stream from images which are already in JPEG format.
|
||||
|
||||
To create an AVI stream from images in DIB format use the function
|
||||
<b>AVIWrapper::CreateAVIStreamFromDIBs()</b> instead.
|
||||
*/
|
||||
void AVIWrapper::CreateAVIStreamFromJPEGs( int w, int h, int bitcount, DWORD sampleRate, DWORD quality, const char* pName /*= "default"*/ )
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// no 'handler' compression! This section works for already compressed images
|
||||
BITMAPINFOHEADER BmpHeader;
|
||||
SetupStreamStructs( BmpHeader, w, h, bitcount, sampleRate, quality, pName, codecMorganMjpg );
|
||||
BmpHeader.biCompression = CodecToFourccCode( codecMorganMjpg );
|
||||
const HRESULT result = AVIStreamSetFormat( m_pAVIStream, 0, &BmpHeader, sizeof( BITMAPINFOHEADER ) );
|
||||
if( result != AVIERR_OK )
|
||||
{
|
||||
CloseStreamsAndFiles();
|
||||
throw AVIWrapperException( AVIErrorToString( result ).c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
/*!
|
||||
\brief Opens an AVI file.
|
||||
\param filename The name of the file to be created/opened/used.
|
||||
\param mode The access mode for this file.
|
||||
|
||||
Opens and creates an AVI file in the mode specified by the \e mode parameter
|
||||
See MSDN for details about the available modes.
|
||||
*/
|
||||
void AVIWrapper::OpenAVIFile( const char* pFilename, UINT mode /* = OF_READ */ )
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if( m_pAVIFile )
|
||||
{
|
||||
throw AVIWrapperException( "OpenAVIFile: Another file has been opened already" );
|
||||
}
|
||||
if( !pFilename )
|
||||
{
|
||||
throw AVIWrapperException( "OpenAVIFile: No valid filename has been specified" );
|
||||
}
|
||||
const HRESULT result = AVIFileOpen( &m_pAVIFile, pFilename, mode, 0 );
|
||||
if( result != AVIERR_OK )
|
||||
{
|
||||
throw AVIWrapperException( AVIErrorToString( result ).c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
/*!
|
||||
\brief Stores one image in the AVI stream
|
||||
\param data Pointer to the image data
|
||||
\param size Size (in bytes) of the memory block pointed to by \e data
|
||||
|
||||
This function stores one image in the specified stream.
|
||||
*/
|
||||
void AVIWrapper::SaveDataToAVIStream( unsigned char* pData, int size )
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
PAVISTREAM pAVIStream = ( m_pAVIStreamCompressed ) ? m_pAVIStreamCompressed : m_pAVIStream;
|
||||
if( !pAVIStream )
|
||||
{
|
||||
throw AVIWrapperException( "SaveDataToAVIStream: Stream pointer invalid" );
|
||||
}
|
||||
const HRESULT result = AVIStreamWrite( pAVIStream, m_AVIStreamFrameCounter++, 1, pData, size, AVIIF_KEYFRAME, 0, 0 );
|
||||
if( result != AVIERR_OK )
|
||||
{
|
||||
throw AVIWrapperException( AVIErrorToString( result ).c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void AVIWrapper::SetupStreamStructs( BITMAPINFOHEADER& BmpHeader, int w, int h, int bitcount, DWORD sampleRate, DWORD quality, const char* pName /*= "default"*/, CODEC_T codec /*= codecMax*/ )
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if( !m_pAVIFile )
|
||||
{
|
||||
throw AVIWrapperException( "CreateNewAVIStream: No file has been opened so far" );
|
||||
}
|
||||
if( strlen( pName ) > sizeof( m_AVIStreamInfo.szName ) )
|
||||
{
|
||||
throw AVIWrapperException( "CreateNewAVIStream: stream name too long" );
|
||||
}
|
||||
if( m_pAVIStream || m_pAVIStreamCompressed )
|
||||
{
|
||||
throw AVIWrapperException( "CreateNewAVIStream: There is already an open stream" );
|
||||
}
|
||||
// setup AVISTREAMINFO structure
|
||||
memset( &m_AVIStreamInfo, 0, sizeof( AVISTREAMINFO ) );
|
||||
m_AVIStreamInfo.fccType = streamtypeVIDEO;
|
||||
m_AVIStreamInfo.fccHandler = CodecToFourccCode( codec );
|
||||
m_AVIStreamInfo.wPriority = 10;
|
||||
m_AVIStreamInfo.dwScale = 1;
|
||||
m_AVIStreamInfo.dwRate = sampleRate;
|
||||
m_AVIStreamInfo.dwQuality = quality;
|
||||
m_AVIStreamInfo.rcFrame.right = w;
|
||||
m_AVIStreamInfo.rcFrame.bottom = h;
|
||||
mv_strncpy_s( m_AVIStreamInfo.szName, pName, sizeof( m_AVIStreamInfo.szName ) );
|
||||
|
||||
const HRESULT result = AVIFileCreateStream( m_pAVIFile, &m_pAVIStream, &m_AVIStreamInfo );
|
||||
if( result != AVIERR_OK )
|
||||
{
|
||||
throw AVIWrapperException( AVIErrorToString( result ).c_str() );
|
||||
}
|
||||
// setup BITMAPINFOHEADER structure
|
||||
memset( &BmpHeader, 0, sizeof( BITMAPINFOHEADER ) );
|
||||
BmpHeader.biSize = sizeof( BITMAPINFOHEADER );
|
||||
BmpHeader.biWidth = w;
|
||||
BmpHeader.biHeight = h;
|
||||
BmpHeader.biPlanes = 1;
|
||||
BmpHeader.biBitCount = static_cast<WORD>( bitcount );
|
||||
|
||||
// setup internals
|
||||
m_AVIStreamFrameCounter = 0;
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
//----------------------------------------------------------------------------------------
|
||||
#ifndef aviwrapperH
|
||||
#define aviwrapperH aviwrapperH
|
||||
//----------------------------------------------------------------------------------------
|
||||
#include "avihelper.h"
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
class AVIWrapper
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// member data
|
||||
/// Keeps track about the number of images stored in the actual stream
|
||||
int m_AVIStreamFrameCounter;
|
||||
/// pointer to the structure describing the AVI-file
|
||||
PAVIFILE m_pAVIFile;
|
||||
/// pointer to an uncompressed AVI stream
|
||||
PAVISTREAM m_pAVIStream;
|
||||
/// pointer to a compressed AVI stream (this is used when a compression handler is used)
|
||||
PAVISTREAM m_pAVIStreamCompressed;
|
||||
/// A structure containing information about the AVI stream
|
||||
AVISTREAMINFO m_AVIStreamInfo;
|
||||
/// A structure for storing the compression options of the AVI stream
|
||||
AVICOMPRESSOPTIONS m_AVICompressionOptions;
|
||||
/// The used codec
|
||||
DWORD m_codec;
|
||||
/// Usage count for this class
|
||||
static unsigned int m_usageCount;
|
||||
// functions
|
||||
void CloseStreamsAndFiles( void );
|
||||
void SetupStreamStructs( BITMAPINFOHEADER& BmpHeader, int w, int h, int bitcount, DWORD sampleRate, DWORD quality, const char* pName = "default", CODEC_T codec = codecMax );
|
||||
/// Do not allow copy construction
|
||||
AVIWrapper( const AVIWrapper& scr );
|
||||
public:
|
||||
// construction/destruction
|
||||
explicit AVIWrapper( const char* pFilename = 0, UINT mode = OF_READ );
|
||||
~AVIWrapper( void );
|
||||
|
||||
// user interface
|
||||
void CloseAVIFile( void );
|
||||
void CreateAVIStreamFromDIBs( int w, int h, int bitcount, DWORD sampleRate, DWORD quality, const char* pName = "default", CODEC_T codec = codecMax );
|
||||
void CreateAVIStreamFromJPEGs( int w, int h, int bitcount, DWORD sampleRate, DWORD quality, const char* pName = "default" );
|
||||
const char* GetStreamName( void ) const
|
||||
{
|
||||
return m_AVIStreamInfo.szName;
|
||||
}
|
||||
bool UsesCompressionHandler( void ) const
|
||||
{
|
||||
return m_codec != CodecToFourccCode( codecNoCompression );
|
||||
}
|
||||
void OpenAVIFile( const char* pFilename, UINT mode = OF_READ );
|
||||
void SaveDataToAVIStream( unsigned char* pData, int size );
|
||||
};
|
||||
|
||||
#endif // aviwrapperH
|
@ -0,0 +1,545 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef exampleHelperH
|
||||
#define exampleHelperH exampleHelperH
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <mvIMPACT_CPP/mvIMPACT_acquire.h>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template<class _Ty>
|
||||
class DisplayDictEntry
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
public:
|
||||
void operator()( const std::pair<std::string, _Ty>& data ) const
|
||||
{
|
||||
std::cout << " [" << data.second << "]: " << data.first << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class DisplayComponent
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
public:
|
||||
void operator()( const Component& data ) const
|
||||
{
|
||||
if( data.isValid() )
|
||||
{
|
||||
std::cout << " " << data.name() << "(" << data.typeAsString() << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class DisplayProperty
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
public:
|
||||
void operator()( const std::pair<std::string, mvIMPACT::acquire::Property>& data ) const
|
||||
{
|
||||
if( data.second.isValid() )
|
||||
{
|
||||
std::cout << data.first << ": " << data.second.readSArray() << "(" << data.second.flagsAsString() << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template<class _Ty>
|
||||
void DisplayPropertyDictionary( const mvIMPACT::acquire::Property& p )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
_Ty prop( p );
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1300) // is 'old' VC 6 Microsoft compiler?
|
||||
std::vector<std::pair<std::string, _Ty::value_type> > dict;
|
||||
prop.getTranslationDict( dict );
|
||||
std::for_each( dict.begin(), dict.end(), DisplayDictEntry<_Ty::value_type>() );
|
||||
#else
|
||||
std::vector<std::pair<std::string, typename _Ty::value_type> > dict;
|
||||
prop.getTranslationDict( dict );
|
||||
std::for_each( dict.begin(), dict.end(), DisplayDictEntry<typename _Ty::value_type>() );
|
||||
#endif // #ifdef _MSC_VER
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \brief Checks is a certain value for property is supported.
|
||||
template<class _Tx>
|
||||
bool supportsEnumStringValue( const _Tx& prop, const std::string& value )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( prop.hasDict() )
|
||||
{
|
||||
typename std::vector<std::string> sequence;
|
||||
prop.getTranslationDictStrings( sequence );
|
||||
return std::find( sequence.begin(), sequence.end(), value ) != sequence.end();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \brief Checks is a certain value for property is supported.
|
||||
template<class _Tx, typename _Ty>
|
||||
bool supportsValue( const _Tx& prop, const _Ty& value )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( prop.hasDict() )
|
||||
{
|
||||
typename std::vector<_Ty> sequence;
|
||||
prop.getTranslationDictValues( sequence );
|
||||
return std::find( sequence.begin(), sequence.end(), value ) != sequence.end();
|
||||
}
|
||||
|
||||
if( prop.hasMinValue() && ( prop.getMinValue() > value ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if( prop.hasMaxValue() && ( prop.getMaxValue() < value ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \brief Sets a property to a certain value if this value is supported.
|
||||
template<typename _Ty, typename _Tx>
|
||||
void conditionalSetProperty( const _Ty& prop, const _Tx& value, bool boSilent = false )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( prop.isValid() && prop.isWriteable() && supportsValue( prop, value ) )
|
||||
{
|
||||
prop.write( value );
|
||||
if( !boSilent )
|
||||
{
|
||||
std::cout << "Property '" << prop.name() << "' set to '" << prop.readS() << "'." << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \brief Sets a property to a certain value if this value is supported.
|
||||
template<typename _Ty>
|
||||
void conditionalSetEnumPropertyByString( const _Ty& prop, const std::string& value, bool boSilent = false )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( prop.isValid() && prop.isWriteable() && supportsEnumStringValue( prop, value ) )
|
||||
{
|
||||
prop.writeS( value );
|
||||
if( !boSilent )
|
||||
{
|
||||
std::cout << "Property '" << prop.name() << "' set to '" << prop.readS() << "'." << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// This function makes heavy use of strings. In real world applications
|
||||
/// this can be avoided if optimal performance is crucial. All properties can be modified
|
||||
/// via strings, but most properties can also be modified with numerical (int / double )
|
||||
/// values, which is much faster, but not as descriptive for a sample application
|
||||
inline void displayPropertyData( const mvIMPACT::acquire::Property& prop )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
const std::string name( prop.name() );
|
||||
std::cout << std::endl
|
||||
<< "Property '" << name << "'(display name: '" << prop.displayName() << "', type: " << prop.typeAsString() << ") currently specifies the following flags: " << prop.flagsAsString() << std::endl
|
||||
<< std::endl;
|
||||
const std::string doc( prop.docString() );
|
||||
if( !doc.empty() )
|
||||
{
|
||||
std::cout << "The following documentation has been reported by the driver for this feature: " << std::endl
|
||||
<< doc << std::endl
|
||||
<< std::endl;
|
||||
}
|
||||
if( prop.selectedFeatureCount() > 0 )
|
||||
{
|
||||
std::vector<Component> selectedFeatureList;
|
||||
prop.selectedFeatures( selectedFeatureList );
|
||||
std::cout << "The following features are selected by this feature(Whenever the current feature is modified, all selected features might change):" << std::endl;
|
||||
std::for_each( selectedFeatureList.begin(), selectedFeatureList.end(), DisplayComponent() );
|
||||
std::cout << std::endl;
|
||||
}
|
||||
if( prop.selectingFeatureCount() > 0 )
|
||||
{
|
||||
std::vector<Component> selectingFeatureList;
|
||||
prop.selectingFeatures( selectingFeatureList );
|
||||
std::cout << "The following features select this feature(Whenever a selecting features is modified, a selected one might change):" << std::endl;
|
||||
std::for_each( selectingFeatureList.begin(), selectingFeatureList.end(), DisplayComponent() );
|
||||
std::cout << std::endl;
|
||||
}
|
||||
if( prop.hasMinValue() )
|
||||
{
|
||||
std::cout << "The minimum value of '" << name << "' is " << prop.readS( mvIMPACT::acquire::plMinValue ) << std::endl;
|
||||
}
|
||||
if( prop.hasMaxValue() )
|
||||
{
|
||||
std::cout << "The maximum value of '" << name << "' is " << prop.readS( mvIMPACT::acquire::plMaxValue ) << std::endl;
|
||||
}
|
||||
if( prop.hasStepWidth() )
|
||||
{
|
||||
std::cout << "The increment of '" << name << "' is " << prop.readS( mvIMPACT::acquire::plStepWidth ) << std::endl;
|
||||
}
|
||||
if( prop.hasDict() )
|
||||
{
|
||||
std::cout << "'" << name << "' defines a dictionary. Valid values are: " << std::endl;
|
||||
mvIMPACT::acquire::TComponentType type = prop.type();
|
||||
if( type == mvIMPACT::acquire::ctPropInt )
|
||||
{
|
||||
DisplayPropertyDictionary<mvIMPACT::acquire::PropertyI>( prop );
|
||||
}
|
||||
else if( type == mvIMPACT::acquire::ctPropInt64 )
|
||||
{
|
||||
DisplayPropertyDictionary<mvIMPACT::acquire::PropertyI64>( prop );
|
||||
}
|
||||
else if( type == mvIMPACT::acquire::ctPropFloat )
|
||||
{
|
||||
DisplayPropertyDictionary<mvIMPACT::acquire::PropertyF>( prop );
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Error! Unhandled enum prop type: " << prop.typeAsString() << std::endl;
|
||||
}
|
||||
}
|
||||
std::cout << "The current value of '" << name << "' is: '" << prop.readS() << "'" << std::endl;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool displayPropertyDataWithValidation( const mvIMPACT::acquire::Property& prop, const std::string& name )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( !prop.isValid() )
|
||||
{
|
||||
std::cout << "Property '" << name << "' is not supported/available." << std::endl;
|
||||
return false;
|
||||
}
|
||||
displayPropertyData( prop );
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Start the acquisition manually if this was requested(this is to prepare the driver for data capture and tell the device to start streaming data)
|
||||
inline void manuallyStartAcquisitionIfNeeded( mvIMPACT::acquire::Device* pDev, const mvIMPACT::acquire::FunctionInterface& fi )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( pDev->acquisitionStartStopBehaviour.read() == mvIMPACT::acquire::assbUser )
|
||||
{
|
||||
const mvIMPACT::acquire::TDMR_ERROR result = static_cast<mvIMPACT::acquire::TDMR_ERROR>( fi.acquisitionStart() );
|
||||
if( result != mvIMPACT::acquire::DMR_NO_ERROR )
|
||||
{
|
||||
std::cout << "'FunctionInterface.acquisitionStart' returned with an unexpected result: " << result
|
||||
<< "(" << mvIMPACT::acquire::ImpactAcquireException::getErrorCodeAsString( result ) << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Stop the acquisition manually if this was requested
|
||||
inline void manuallyStopAcquisitionIfNeeded( mvIMPACT::acquire::Device* pDev, const mvIMPACT::acquire::FunctionInterface& fi )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( pDev->acquisitionStartStopBehaviour.read() == mvIMPACT::acquire::assbUser )
|
||||
{
|
||||
const mvIMPACT::acquire::TDMR_ERROR result = static_cast<mvIMPACT::acquire::TDMR_ERROR>( fi.acquisitionStop() );
|
||||
if( result != mvIMPACT::acquire::DMR_NO_ERROR )
|
||||
{
|
||||
std::cout << "'FunctionInterface.acquisitionStop' returned with an unexpected result: " << result
|
||||
<< "(" << mvIMPACT::acquire::ImpactAcquireException::getErrorCodeAsString( result ) << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// This function makes heavy use of strings. In real world applications
|
||||
/// this can be avoided if optimal performance is crucial. All properties can be modified
|
||||
/// via strings, but most properties can also be modified with numerical (int / double )
|
||||
/// values, which is much faster, but not as descriptive for a sample application
|
||||
inline void modifyPropertyValue( const mvIMPACT::acquire::Property& prop, const std::string& param = "", const std::string& index = "" )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
try
|
||||
{
|
||||
const std::string name( prop.name() );
|
||||
if( prop.isWriteable() )
|
||||
{
|
||||
int valIndex = 0;
|
||||
if( param.empty() )
|
||||
{
|
||||
std::cout << "Enter the new value for '" << name << "': ";
|
||||
std::string val;
|
||||
std::cin >> val;
|
||||
// remove the '\n' from the stream
|
||||
std::cin.get();
|
||||
if( prop.valCount() > 1 )
|
||||
{
|
||||
std::cout << "'" << name << "' defines " << prop.valCount() << " values. Enter the index (zero-based) of the value to modify: ";
|
||||
std::cin >> valIndex;
|
||||
// remove the '\n' from the stream
|
||||
std::cin.get();
|
||||
}
|
||||
prop.writeS( val, valIndex );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !index.empty() )
|
||||
{
|
||||
valIndex = atoi( index.c_str() );
|
||||
}
|
||||
prop.writeS( param, valIndex );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "'" << name << "' is read-only, thus can't be modified." << std::endl;
|
||||
}
|
||||
}
|
||||
catch( const mvIMPACT::acquire::ImpactAcquireException& e )
|
||||
{
|
||||
std::cout << "An exception occurred: " << e.getErrorString() << "(error code: " << e.getErrorCodeAsString() << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline void displayAndModifyPropertyDataWithValidation( const mvIMPACT::acquire::Property& prop, const std::string& name )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( displayPropertyDataWithValidation( prop, name ) )
|
||||
{
|
||||
modifyPropertyValue( prop );
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline std::ostream& operator<<( std::ostream& out, const mvIMPACT::acquire::Property& prop )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
out << prop.name() << ": " << prop.readS();
|
||||
return out;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \brief Allows string comparison with a defined character to ignore
|
||||
/**
|
||||
* This function allows a tolerant string compare. If \a candidate ends with \a wildcard
|
||||
* \a candidate can be shorter then \a searchString as the rest of the string will be
|
||||
* ignored. This is a helper function used internally by <b>DeviceManager</b> objects.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* \code
|
||||
* wildcard = '*'
|
||||
* s1 = "blablabla"
|
||||
* match( s1, "bl*bl*bla", '*' ); // will return 0
|
||||
* // will return 0 ('*' is the default value for parameter 3 )
|
||||
* match( s1, "bl*" );
|
||||
* // the next call will return -1 as the first character MUST
|
||||
* // be either a 'b' or the wildcard character.
|
||||
* match( s1, "a*" );
|
||||
* \endcode
|
||||
* \return
|
||||
* - 0 if successful
|
||||
* - -1 otherwise
|
||||
*/
|
||||
template<class _Elem, class _Traits, class _Ax>
|
||||
int match( const std::basic_string<_Elem, _Traits, _Ax>& searchString, const std::basic_string<_Elem, _Traits, _Ax>& candidate, _Elem wildcard )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
typename std::basic_string<_Elem, _Traits, _Ax>::size_type searchLength = searchString.length();
|
||||
// determine search length
|
||||
if( candidate.length() < searchString.length() )
|
||||
{
|
||||
if( candidate.empty() )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( candidate[candidate.length() - 1] != wildcard )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
searchLength = candidate.length() - 1;
|
||||
}
|
||||
// search
|
||||
for( typename std::basic_string<_Elem, _Traits, _Ax>::size_type i = 0; i < searchLength; i++ )
|
||||
{
|
||||
if( ( candidate[i] != searchString[i] ) && ( candidate[i] != wildcard ) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef bool( *SUPPORTED_DEVICE_CHECK )( const mvIMPACT::acquire::Device* const );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline mvIMPACT::acquire::Device* getDeviceFromUserInput( const mvIMPACT::acquire::DeviceManager& devMgr, SUPPORTED_DEVICE_CHECK pSupportedDeviceCheckFn = 0, bool boSilent = false, bool boAutomaticallyUseGenICamInterface = true )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
const unsigned int devCnt = devMgr.deviceCount();
|
||||
if( devCnt == 0 )
|
||||
{
|
||||
std::cout << "No compliant device found!" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::set<unsigned int> validDeviceNumbers;
|
||||
|
||||
// display every device detected that matches
|
||||
for( unsigned int i = 0; i < devCnt; i++ )
|
||||
{
|
||||
Device* pDev = devMgr[i];
|
||||
if( pDev )
|
||||
{
|
||||
if( !pSupportedDeviceCheckFn || pSupportedDeviceCheckFn( pDev ) )
|
||||
{
|
||||
std::cout << "[" << i << "]: " << pDev->serial.read() << " (" << pDev->product.read() << ", " << pDev->family.read();
|
||||
if( pDev->interfaceLayout.isValid() )
|
||||
{
|
||||
if( boAutomaticallyUseGenICamInterface )
|
||||
{
|
||||
// if this device offers the 'GenICam' interface switch it on, as this will
|
||||
// allow are better control over GenICam compliant devices
|
||||
conditionalSetProperty( pDev->interfaceLayout, dilGenICam, true );
|
||||
}
|
||||
std::cout << ", interface layout: " << pDev->interfaceLayout.readS();
|
||||
}
|
||||
if( pDev->acquisitionStartStopBehaviour.isValid() )
|
||||
{
|
||||
// if this device offers a user defined acquisition start/stop behaviour
|
||||
// enable it as this allows finer control about the streaming behaviour
|
||||
conditionalSetProperty( pDev->acquisitionStartStopBehaviour, assbUser, true );
|
||||
std::cout << ", acquisition start/stop behaviour: " << pDev->acquisitionStartStopBehaviour.readS();
|
||||
}
|
||||
if( pDev->interfaceLayout.isValid() && !pDev->interfaceLayout.isWriteable() )
|
||||
{
|
||||
if( pDev->isInUse() )
|
||||
{
|
||||
std::cout << ", !!!ALREADY IN USE!!!";
|
||||
}
|
||||
}
|
||||
std::cout << ")" << std::endl;
|
||||
validDeviceNumbers.insert( i );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( validDeviceNumbers.empty() )
|
||||
{
|
||||
std::cout << devMgr.deviceCount() << " devices have been detected:" << std::endl;
|
||||
for( unsigned int i = 0; i < devCnt; i++ )
|
||||
{
|
||||
Device* pDev = devMgr[i];
|
||||
if( pDev )
|
||||
{
|
||||
std::cout << " [" << i << "]: " << pDev->serial.read() << " (" << pDev->product.read() << ", " << pDev->family.read() << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
std::cout << "However none of these devices seems to be supported by this sample." << std::endl << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// get user input
|
||||
std::cout << std::endl << "Please enter the number in front of the listed device followed by [ENTER] to open it: ";
|
||||
unsigned int devNr = 0;
|
||||
std::cin >> devNr;
|
||||
// remove the '\n' from the stream
|
||||
std::cin.get();
|
||||
|
||||
if( validDeviceNumbers.find( devNr ) == validDeviceNumbers.end() )
|
||||
{
|
||||
std::cout << "Invalid selection!" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( !boSilent )
|
||||
{
|
||||
std::cout << "Using device number " << devNr << "." << std::endl;
|
||||
}
|
||||
return devMgr[devNr];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline std::vector<mvIMPACT::acquire::Device*>::size_type getValidDevices( const mvIMPACT::acquire::DeviceManager& devMgr, std::vector<mvIMPACT::acquire::Device*>& v, SUPPORTED_DEVICE_CHECK pSupportedDeviceCheckFn = 0 )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
const unsigned int devCnt = devMgr.deviceCount();
|
||||
// display every device detected that matches
|
||||
for( unsigned int i = 0; i < devCnt; i++ )
|
||||
{
|
||||
Device* pDev = devMgr[i];
|
||||
if( pDev )
|
||||
{
|
||||
if( !pSupportedDeviceCheckFn || pSupportedDeviceCheckFn( pDev ) )
|
||||
{
|
||||
v.push_back( pDev );
|
||||
}
|
||||
}
|
||||
}
|
||||
return v.size();
|
||||
}
|
||||
|
||||
#if defined(linux) || defined(__linux) || defined(__linux__)
|
||||
# include <fcntl.h>
|
||||
# include <stdio.h>
|
||||
# include <sys/types.h>
|
||||
# include <termios.h>
|
||||
# include <unistd.h>
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \brief Checks if something was written to a certain file descriptor
|
||||
/** \return
|
||||
* - 0 if timeout did elapse
|
||||
* - 1 otherwise
|
||||
*/
|
||||
inline unsigned waitForInput( int maxWait_sec, int fd )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
fd_set rfds;
|
||||
struct timeval tv;
|
||||
|
||||
FD_ZERO( &rfds );
|
||||
#ifndef __clang_analyzer__ // See https://bugs.llvm.org/show_bug.cgi?id=8920
|
||||
FD_SET( fd, &rfds );
|
||||
#endif // #ifndef __clang_analyzer__
|
||||
|
||||
tv.tv_sec = maxWait_sec;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
return select( fd + 1, &rfds, NULL, NULL, &tv );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** \return
|
||||
* - 1 if a key has been pressed since the last call to this function
|
||||
* - 0 otherwise
|
||||
*/
|
||||
inline int checkKeyboardInput( void )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
struct termios oldt, newt;
|
||||
tcgetattr( STDIN_FILENO, &oldt );
|
||||
newt = oldt;
|
||||
newt.c_lflag &= ~( ICANON | ECHO );
|
||||
tcsetattr( STDIN_FILENO, TCSANOW, &newt );
|
||||
const int oldf = fcntl( STDIN_FILENO, F_GETFL, 0 );
|
||||
fcntl( STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK );
|
||||
const int ch = getchar();
|
||||
tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
|
||||
fcntl( STDIN_FILENO, F_SETFL, oldf );
|
||||
if( ch != EOF )
|
||||
{
|
||||
// ungetc(ch, stdin);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif // #if defined(linux) || defined(__linux) || defined(__linux__)
|
||||
|
||||
#endif // exampleHelperH
|
@ -0,0 +1,595 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "exampleHelper_C.h"
|
||||
|
||||
#define BUF_SIZE (32)
|
||||
#define BUF_SIZE_LARGE (256)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
int getIntValFromSTDIn( void )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
int value;
|
||||
int conversionResult = 0;
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400) // is at least VC 2005 compiler?
|
||||
conversionResult = scanf_s( "%d", &value );
|
||||
#else
|
||||
conversionResult = scanf( "%d", &value );
|
||||
#endif // #if defined(_MSC_VER) && (_MSC_VER >= 1400) // is at least VC 2005 compiler?
|
||||
if( conversionResult != 1 )
|
||||
{
|
||||
printf( "Conversion error: Expected: 1, conversion result: %d.\n", conversionResult );
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
int getPropI( HOBJ hProp, int index )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
int value = 0;
|
||||
TPROPHANDLING_ERROR result = PROPHANDLING_NO_ERROR;
|
||||
|
||||
if( ( result = OBJ_GetI( hProp, &value, index ) ) != PROPHANDLING_NO_ERROR )
|
||||
{
|
||||
printf( "getPropI: Failed to read property value(%s).\n", DMR_ErrorCodeToString( result ) );
|
||||
exit( 42 );
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void setPropI( HOBJ hProp, int value, int index )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
TPROPHANDLING_ERROR result = PROPHANDLING_NO_ERROR;
|
||||
|
||||
if( ( result = OBJ_SetI( hProp, value, index ) ) != PROPHANDLING_NO_ERROR )
|
||||
{
|
||||
printf( "setPropI: Failed to write property value(%s).\n", DMR_ErrorCodeToString( result ) );
|
||||
exit( 42 );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
int64_type getPropI64( HOBJ hProp, int index )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
int64_type value = 0;
|
||||
TPROPHANDLING_ERROR result = PROPHANDLING_NO_ERROR;
|
||||
|
||||
if( ( result = OBJ_GetI64( hProp, &value, index ) ) != PROPHANDLING_NO_ERROR )
|
||||
{
|
||||
printf( "getPropI: Failed to read property value(%s).\n", DMR_ErrorCodeToString( result ) );
|
||||
exit( 42 );
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void setPropI64( HOBJ hProp, int64_type value, int index )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
TPROPHANDLING_ERROR result = PROPHANDLING_NO_ERROR;
|
||||
|
||||
if( ( result = OBJ_SetI64( hProp, value, index ) ) != PROPHANDLING_NO_ERROR )
|
||||
{
|
||||
printf( "setPropI: Failed to write property value(%s).\n", DMR_ErrorCodeToString( result ) );
|
||||
exit( 42 );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void* getPropP( HOBJ hProp, int index )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
void* value = 0;
|
||||
TPROPHANDLING_ERROR result = PROPHANDLING_NO_ERROR;
|
||||
|
||||
if( ( result = OBJ_GetP( hProp, &value, index ) ) != PROPHANDLING_NO_ERROR )
|
||||
{
|
||||
printf( "getPropP: Failed to read property value(%s).\n", DMR_ErrorCodeToString( result ) );
|
||||
exit( 42 );
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void setPropP( HOBJ hProp, void* value, int index )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
TPROPHANDLING_ERROR result = PROPHANDLING_NO_ERROR;
|
||||
|
||||
if( ( result = OBJ_SetP( hProp, value, index ) ) != PROPHANDLING_NO_ERROR )
|
||||
{
|
||||
printf( "setPropP: Failed to write property value(%s).\n", DMR_ErrorCodeToString( result ) );
|
||||
exit( 42 );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void setPropS( HOBJ hProp, const char* pVal, int index )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
TPROPHANDLING_ERROR result = PROPHANDLING_NO_ERROR;
|
||||
|
||||
if( ( result = OBJ_SetS( hProp, pVal, index ) ) != PROPHANDLING_NO_ERROR )
|
||||
{
|
||||
printf( "setPropS: Failed to write property value %s :%s.\n", pVal, DMR_ErrorCodeToString( result ) );
|
||||
exit( 42 );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This function will try to obtain the handle to a certain driver feature
|
||||
HOBJ getDriverFeature( HDRV hDrv, const char* pFeatureName, const char* pFeatureType, const char* pAddListName, TDMR_ListType type, unsigned int searchMode )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
TDMR_ERROR dmrResult = DMR_NO_ERROR;
|
||||
HOBJ hObj = INVALID_ID;
|
||||
HLIST baseList = INVALID_ID;
|
||||
|
||||
// try to locate the base list for these property
|
||||
if( ( dmrResult = DMR_FindList( hDrv, pAddListName, type, 0, &baseList ) ) == DMR_NO_ERROR )
|
||||
{
|
||||
// try to locate the property
|
||||
TPROPHANDLING_ERROR objResult;
|
||||
if( ( objResult = OBJ_GetHandleEx( baseList, pFeatureName, &hObj, searchMode, INT_MAX ) ) != PROPHANDLING_NO_ERROR )
|
||||
{
|
||||
printf( "OBJ_GetHandleEx for '%s' failed: %d Handle: %d. This %s might not be supported by this device\n", pFeatureName, objResult, hObj, pFeatureType );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "DMR_FindList failed: %d. Lists of type %d are not available for this device\n", dmrResult, type );
|
||||
}
|
||||
return hObj;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This function will try to obtain the handle to a certain driver feature list
|
||||
HOBJ getDriverList( HDRV hDrv, const char* pListName, const char* pAddListName, TDMR_ListType type )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return getDriverFeature( hDrv, pListName, "list", pAddListName, type, smIgnoreProperties | smIgnoreMethods );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This function will try to obtain the handle to a certain driver property
|
||||
HOBJ getDriverProperty( HDRV hDrv, const char* pPropName, const char* pAddListName, TDMR_ListType type )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return getDriverFeature( hDrv, pPropName, "property", pAddListName, type, smIgnoreLists | smIgnoreMethods );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This function will try to obtain the handle to a certain driver property
|
||||
HOBJ getDriverMethod( HDRV hDrv, const char* pPropName, const char* pAddListName, TDMR_ListType type )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return getDriverFeature( hDrv, pPropName, "method", pAddListName, type, smIgnoreProperties | smIgnoreLists );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
HOBJ getDeviceProp( HDEV hDev, const char* pPropName )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
TPROPHANDLING_ERROR objResult;
|
||||
HOBJ hProp = INVALID_ID;
|
||||
|
||||
// try to locate the property
|
||||
if( ( objResult = OBJ_GetHandleEx( hDev, pPropName, &hProp, 0, -1 ) ) != PROPHANDLING_NO_ERROR )
|
||||
{
|
||||
printf( "OBJ_GetHandleEx failed for property '%s': %d Handle: %d\n", pPropName, objResult, hProp );
|
||||
}
|
||||
return hProp;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
HOBJ getInfoProp( HDRV hDrv, const char* pPropName )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return getDriverProperty( hDrv, pPropName, 0, dmltInfo );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
HOBJ getIOSubSystemProp( HDRV hDrv, const char* pPropName )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return getDriverProperty( hDrv, pPropName, 0, dmltIOSubSystem );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
HOBJ getRequestCtrlProp( HDRV hDrv, const char* pRequestCtrlName, const char* pPropName )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return getDriverProperty( hDrv, pPropName, pRequestCtrlName, dmltRequestCtrl );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
HOBJ getRequestProp( HDRV hDrv, int requestNr, const char* pPropName )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
char buf[BUF_SIZE];
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400) // is at least VC 2005 compiler?
|
||||
sprintf_s( buf, BUF_SIZE, "Entry %d", requestNr );
|
||||
#else
|
||||
sprintf( buf, "Entry %d", requestNr );
|
||||
#endif // #if defined(_MSC_VER) && (_MSC_VER >= 1400) // is at least VC 2005 compiler?
|
||||
return getDriverProperty( hDrv, pPropName, buf, dmltRequest );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
HOBJ getSettingProp( HDRV hDrv, const char* pSettingName, const char* pPropName )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return getDriverProperty( hDrv, pPropName, pSettingName, dmltSetting );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
HOBJ getSettingMethod( HDRV hDrv, const char* pSettingName, const char* pMethodName )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return getDriverMethod( hDrv, pMethodName, pSettingName, dmltSetting );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
HOBJ getStatisticProp( HDRV hDrv, const char* pPropName )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return getDriverProperty( hDrv, pPropName, 0, dmltStatistics );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
HOBJ getSystemSettingProp( HDRV hDrv, const char* pPropName )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return getDriverProperty( hDrv, pPropName, 0, dmltSystemSettings );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
TPROPHANDLING_ERROR getStringValue( HOBJ hObj, char** pBuf, int index )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
size_t bufSize = DEFAULT_STRING_SIZE_LIMIT;
|
||||
TPROPHANDLING_ERROR result = PROPHANDLING_NO_ERROR;
|
||||
static const int BUFFER_INCREMENT_FACTOR = 2;
|
||||
|
||||
*pBuf = ( char* )calloc( 1, bufSize );
|
||||
while( ( result = OBJ_GetS( hObj, *pBuf, bufSize, index ) ) == PROPHANDLING_INPUT_BUFFER_TOO_SMALL )
|
||||
{
|
||||
bufSize *= BUFFER_INCREMENT_FACTOR;
|
||||
*pBuf = ( char* )realloc( *pBuf, bufSize );
|
||||
}
|
||||
if( result != PROPHANDLING_NO_ERROR )
|
||||
{
|
||||
printf( "Error while reading string property value: Error code: %d(%s).\n", result, DMR_ErrorCodeToString( result ) );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
TPROPHANDLING_ERROR getValueAsString( HOBJ hObj, const char* pFormat, char** pBuf, int index )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
size_t bufSize = DEFAULT_STRING_SIZE_LIMIT;
|
||||
TPROPHANDLING_ERROR result = PROPHANDLING_NO_ERROR;
|
||||
|
||||
*pBuf = ( char* )calloc( 1, bufSize );
|
||||
while( ( result = OBJ_GetSFormattedEx( hObj, *pBuf, &bufSize, pFormat, index ) ) == PROPHANDLING_INPUT_BUFFER_TOO_SMALL )
|
||||
{
|
||||
*pBuf = ( char* )realloc( *pBuf, bufSize );
|
||||
}
|
||||
|
||||
if( result != PROPHANDLING_NO_ERROR )
|
||||
{
|
||||
printf( "Error while reading string property value: Error code: %d(%s).\n", result, DMR_ErrorCodeToString( result ) );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Start the acquisition manually if this was requested(this is to prepare the driver for data capture and tell the device to start streaming data)
|
||||
// Whether this is needed or not depends on the property 'AcquisitionStartStopBehaviour' in the list referenced by 'HDEV'.
|
||||
void manuallyStartAcquisitionIfNeeded( HDRV hDrv )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
const TDMR_ERROR result = DMR_AcquisitionStart( hDrv );
|
||||
if( ( result != DMR_NO_ERROR ) &&
|
||||
( result != DMR_FEATURE_NOT_AVAILABLE ) )
|
||||
{
|
||||
printf( "DMR_AcquisitionStart: Unexpected error(code: %d(%s))\n", result, DMR_ErrorCodeToString( result ) );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Stop the acquisition manually if this was requested.
|
||||
// Whether this is needed or not depends on the property 'AcquisitionStartStopBehaviour' in the list referenced by 'HDEV'.
|
||||
void manuallyStopAcquisitionIfNeeded( HDRV hDrv )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
const TDMR_ERROR result = DMR_AcquisitionStop( hDrv );
|
||||
if( ( result != DMR_NO_ERROR ) &&
|
||||
( result != DMR_FEATURE_NOT_AVAILABLE ) )
|
||||
{
|
||||
printf( "DMR_AcquisitionStop: Unexpected error(code: %d(%s))\n", result, DMR_ErrorCodeToString( result ) );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void modifyEnumPropertyI( HDRV hDrv, const char* pSettingName, const char* pPropName )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
HOBJ hProp = INVALID_ID;
|
||||
unsigned int dictValCount = 0;
|
||||
int* dictVals = NULL;
|
||||
TPROPHANDLING_ERROR result = PROPHANDLING_NO_ERROR;
|
||||
|
||||
printf( "Trying to modify property %s:\n", pPropName );
|
||||
if( ( hProp = getSettingProp( hDrv, pSettingName, pPropName ) ) != INVALID_ID )
|
||||
{
|
||||
if( ( result = readTranslationDictValuesI( hProp, &dictVals, &dictValCount, 0 ) ) == PROPHANDLING_NO_ERROR )
|
||||
{
|
||||
int value = 0;
|
||||
printf( "Please select one of the values listed above: " );
|
||||
value = getIntValFromSTDIn();
|
||||
free( dictVals );
|
||||
// set the new trigger mode
|
||||
if( ( result = OBJ_SetI( hProp, value, 0 ) ) != PROPHANDLING_NO_ERROR )
|
||||
{
|
||||
printf( "Failed to set new value for %s. Error code: %d(%s).\n", pPropName, result, DMR_ErrorCodeToString( result ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
TPROPHANDLING_ERROR readTranslationDictValuesI( HOBJ hObj, int** pDictValues, unsigned int* pDictValCnt, unsigned int silent )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
TPROPHANDLING_ERROR funcResult = PROPHANDLING_NO_ERROR;
|
||||
char** ppBuf = 0;
|
||||
unsigned int i = 0;
|
||||
size_t bufSize = 0;
|
||||
const size_t BUFFER_INCREMENT_FACTOR = 6;
|
||||
|
||||
if( ( funcResult = OBJ_GetDictSize( hObj, pDictValCnt ) ) != PROPHANDLING_NO_ERROR )
|
||||
{
|
||||
return funcResult;
|
||||
}
|
||||
|
||||
*pDictValues = ( int* )calloc( *pDictValCnt, sizeof( int ) );
|
||||
if( !( *pDictValues ) )
|
||||
{
|
||||
printf( "Failed to allocate memory for integer dictionary!\n" );
|
||||
return PROPHANDLING_INPUT_BUFFER_TOO_SMALL;
|
||||
}
|
||||
ppBuf = ( char** )calloc( *pDictValCnt, sizeof( char* ) );
|
||||
if( !ppBuf )
|
||||
{
|
||||
free( *pDictValues );
|
||||
printf( "Failed to allocate memory for string dictionary!\n" );
|
||||
return PROPHANDLING_INPUT_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
bufSize = DEFAULT_STRING_SIZE_LIMIT;
|
||||
for( i = 0; i < *pDictValCnt; i++ )
|
||||
{
|
||||
ppBuf[i] = ( char* )calloc( 1, bufSize );
|
||||
}
|
||||
|
||||
while( ( funcResult = OBJ_GetIDictEntries( hObj, ppBuf, bufSize, *pDictValues, ( size_t ) * pDictValCnt ) ) == PROPHANDLING_INPUT_BUFFER_TOO_SMALL )
|
||||
{
|
||||
bufSize *= BUFFER_INCREMENT_FACTOR;
|
||||
for( i = 0; i < *pDictValCnt; i++ )
|
||||
{
|
||||
ppBuf[i] = ( char* )realloc( ppBuf[i], bufSize );
|
||||
}
|
||||
}
|
||||
|
||||
if( ( funcResult == PROPHANDLING_NO_ERROR ) &&
|
||||
( silent == 0 ) )
|
||||
{
|
||||
printf( "Got the following dictionary:\n" );
|
||||
for( i = 0; i < *pDictValCnt; i++ )
|
||||
{
|
||||
printf( "[%d]: %s(numerical rep: %d)\n", i, ppBuf[i] ? ppBuf[i] : "!NO MEMORY!", ( *pDictValues )[i] );
|
||||
}
|
||||
}
|
||||
|
||||
// free memory again
|
||||
for( i = 0; i < *pDictValCnt; i++ )
|
||||
{
|
||||
free( ppBuf[i] );
|
||||
}
|
||||
free( ppBuf );
|
||||
return funcResult;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void conditionalSetPropI( HOBJ hProp, int value, unsigned int silent )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
unsigned int dictValCount = 0;
|
||||
size_t i = 0;
|
||||
int* dictVals = NULL;
|
||||
TPROPHANDLING_ERROR result = PROPHANDLING_NO_ERROR;
|
||||
char bufName[BUF_SIZE_LARGE];
|
||||
char* pBufValue = 0;
|
||||
|
||||
if( ( result = readTranslationDictValuesI( hProp, &dictVals, &dictValCount, silent ) ) == PROPHANDLING_NO_ERROR )
|
||||
{
|
||||
for( i = 0; i < dictValCount; i++ )
|
||||
{
|
||||
if( dictVals[i] == value )
|
||||
{
|
||||
setPropI( hProp, value, 0 );
|
||||
memset( bufName, '\0', BUF_SIZE_LARGE );
|
||||
OBJ_GetName( hProp, bufName, BUF_SIZE_LARGE );
|
||||
getValueAsString( hProp, 0, &pBufValue, 0 );
|
||||
if( silent == 0 )
|
||||
{
|
||||
printf( "Property '%s' set to '%s'.\n", bufName, pBufValue );
|
||||
}
|
||||
free( pBufValue );
|
||||
break;
|
||||
}
|
||||
}
|
||||
free( dictVals );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "Failed to read translation dictionary from property. Error code: %d(%s).\n", result, DMR_ErrorCodeToString( result ) );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
int getDeviceFromUserInput( HDEV* phDevice, SUPPORTED_DEVICE_CHECK pSupportedDeviceCheckFn, unsigned int automaticallyUseGenICamInterface )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
TDMR_ERROR result = DMR_NO_ERROR;
|
||||
unsigned int i = 0;
|
||||
unsigned int deviceCount = 0;
|
||||
unsigned int deviceNumber = 0;
|
||||
HOBJ hPropSerial = INVALID_ID;
|
||||
HOBJ hPropProduct = INVALID_ID;
|
||||
HOBJ hPropInterfaceLayout = INVALID_ID;
|
||||
HOBJ hPropAcquisitionStartStopBehaviour = INVALID_ID;
|
||||
char* pSerialStringBuffer = NULL;
|
||||
char* pProductStringBuffer = NULL;
|
||||
|
||||
if( ( result = DMR_GetDeviceCount( &deviceCount ) ) != DMR_NO_ERROR )
|
||||
{
|
||||
printf( "DMR_GetDeviceCount failed (code: %d(%s))\n", result, DMR_ErrorCodeToString( result ) );
|
||||
END_APPLICATION;
|
||||
}
|
||||
|
||||
if( deviceCount == 0 )
|
||||
{
|
||||
printf( "No compliant device detected.\n" );
|
||||
END_APPLICATION;
|
||||
}
|
||||
|
||||
printf( "%d compliant devices detected.\n", deviceCount );
|
||||
for( i = 0; i < deviceCount; i++ )
|
||||
{
|
||||
// try to get access to the device
|
||||
if( ( result = DMR_GetDevice( phDevice, dmdsmSerial, "*", i, '*' ) ) != DMR_NO_ERROR )
|
||||
{
|
||||
printf( "DMR_GetDevice(%d) failed (code: %d(%s))\n", i, result, DMR_ErrorCodeToString( result ) );
|
||||
END_APPLICATION;
|
||||
}
|
||||
|
||||
if( ( hPropSerial = getDeviceProp( *phDevice, "Serial" ) ) == INVALID_ID )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
getStringValue( hPropSerial, &pSerialStringBuffer, 0 );
|
||||
if( !pSupportedDeviceCheckFn || pSupportedDeviceCheckFn( *phDevice ) )
|
||||
{
|
||||
if( ( hPropProduct = getDeviceProp( *phDevice, "Product" ) ) == INVALID_ID )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
getStringValue( hPropProduct, &pProductStringBuffer, 0 );
|
||||
printf( "[%d] %s (%s", i, pSerialStringBuffer, pProductStringBuffer );
|
||||
if( ( hPropInterfaceLayout = getDeviceProp( *phDevice, "InterfaceLayout" ) ) != INVALID_ID )
|
||||
{
|
||||
char* pStringBuffer = NULL;
|
||||
getValueAsString( hPropInterfaceLayout, NULL, &pStringBuffer, 0 );
|
||||
if( automaticallyUseGenICamInterface != 0 )
|
||||
{
|
||||
conditionalSetPropI( hPropInterfaceLayout, dilGenICam, 1 );
|
||||
}
|
||||
printf( ", interface layout: %s", pStringBuffer );
|
||||
free( pStringBuffer );
|
||||
}
|
||||
|
||||
if( ( hPropAcquisitionStartStopBehaviour = getDeviceProp( *phDevice, "AcquisitionStartStopBehaviour" ) ) != INVALID_ID )
|
||||
{
|
||||
char* pStringBuffer = NULL;
|
||||
conditionalSetPropI( hPropAcquisitionStartStopBehaviour, assbUser, 1 );
|
||||
getValueAsString( hPropAcquisitionStartStopBehaviour, NULL, &pStringBuffer, 0 );
|
||||
printf( ", acquisition start/stop behaviour: %s", pStringBuffer );
|
||||
free( pStringBuffer );
|
||||
}
|
||||
printf( ")\n" );
|
||||
free( pProductStringBuffer );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "%s is not supported by this application.\n", pSerialStringBuffer );
|
||||
}
|
||||
free( pSerialStringBuffer );
|
||||
}
|
||||
|
||||
printf( "Please enter the number in brackets followed by [ENTER] to open it: " );
|
||||
deviceNumber = getIntValFromSTDIn();
|
||||
// remove the '\n' from the stream
|
||||
fgetc( stdin );
|
||||
|
||||
// try to get access to the selected device
|
||||
if( ( result = DMR_GetDevice( phDevice, dmdsmSerial, "*", deviceNumber, '*' ) ) != DMR_NO_ERROR )
|
||||
{
|
||||
printf( "DMR_GetDevice(%d) failed (code: %d(%s))\n", deviceNumber, result, DMR_ErrorCodeToString( result ) );
|
||||
printf( "DMR_Close: %d\n", DMR_Close() );
|
||||
END_APPLICATION;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
static unsigned int isFeatureFlagSet( HOBJ hObj, TComponentFlag flag )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
TComponentFlag flags;
|
||||
|
||||
if( ( hObj == INVALID_ID ) ||
|
||||
( OBJ_GetFlags( hObj, &flags ) != PROPHANDLING_NO_ERROR ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ( ( flags & flag ) != 0 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned int isFeatureReadable( HOBJ hObj )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return isFeatureFlagSet( hObj, cfReadAccess );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned int isFeatureWriteable( HOBJ hObj )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return isFeatureFlagSet( hObj, cfWriteAccess );
|
||||
}
|
||||
|
||||
#if defined(linux) || defined(__linux) || defined(__linux__)
|
||||
# include <sys/types.h>
|
||||
# include <unistd.h>
|
||||
//-----------------------------------------------------------------------------
|
||||
// returns 0 if timeout, else 1
|
||||
unsigned waitForInput( int maxWait_sec, int fd )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
fd_set rfds;
|
||||
struct timeval tv;
|
||||
|
||||
FD_ZERO( &rfds );
|
||||
FD_SET( fd, &rfds );
|
||||
|
||||
tv.tv_sec = maxWait_sec ;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
return select( fd + 1, &rfds, NULL, NULL, &tv );
|
||||
}
|
||||
#endif // #if defined(linux) || defined(__linux) || defined(__linux__)
|
@ -0,0 +1,71 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef exampleHelper_CH
|
||||
#define exampleHelper_CH exampleHelper_CH
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <mvDeviceManager/Include/mvDeviceManager.h>
|
||||
|
||||
#define END_APPLICATION \
|
||||
printf( "Press [ENTER] to end the application.\n" ); \
|
||||
return getchar() == EOF ? 2 : 1;
|
||||
|
||||
#if defined(linux) || defined(__linux) || defined(__linux__)
|
||||
unsigned waitForInput( int maxWait_sec, int fd );
|
||||
#endif // #if defined(linux) || defined(__linux) || defined(__linux__)
|
||||
|
||||
int getIntValFromSTDIn( void );
|
||||
int getPropI( HOBJ hProp, int index );
|
||||
void setPropI( HOBJ hProp, int value, int index );
|
||||
int64_type getPropI64( HOBJ hProp, int index );
|
||||
void setPropI64( HOBJ hProp, int64_type value, int index );
|
||||
void* getPropP( HOBJ hProp, int index );
|
||||
void setPropP( HOBJ hProp, void* value, int index );
|
||||
void setPropS( HOBJ hProp, const char* pVal, int index );
|
||||
|
||||
HOBJ getDriverList( HDRV hDrv, const char* pListName, const char* pAddListName, TDMR_ListType type );
|
||||
HOBJ getDriverProperty( HDRV hDrv, const char* pPropName, const char* pAddListName, TDMR_ListType type );
|
||||
HOBJ getDriverMethod( HDRV hDrv, const char* pMethodName, const char* pAddListName, TDMR_ListType type );
|
||||
HOBJ getDeviceProp( HDEV hDev, const char* pPropName );
|
||||
HOBJ getInfoProp( HDRV hDrv, const char* pPropName );
|
||||
HOBJ getIOSubSystemProp( HDRV hDrv, const char* pPropName );
|
||||
HOBJ getRequestCtrlProp( HDRV hDrv, const char* pRequestCtrlName, const char* pPropName );
|
||||
HOBJ getRequestProp( HDRV hDrv, int requestNr, const char* pPropName );
|
||||
HOBJ getSettingProp( HDRV hDrv, const char* pSettingName, const char* pPropName );
|
||||
HOBJ getSettingMethod( HDRV hDrv, const char* pSettingName, const char* pMethodName );
|
||||
HOBJ getStatisticProp( HDRV hDrv, const char* pPropName );
|
||||
HOBJ getSystemSettingProp( HDRV hDrv, const char* pPropName );
|
||||
|
||||
unsigned int isFeatureReadable( HOBJ hObj );
|
||||
unsigned int isFeatureWriteable( HOBJ hObj );
|
||||
|
||||
typedef unsigned int( *SUPPORTED_DEVICE_CHECK )( const HDEV );
|
||||
|
||||
int getDeviceFromUserInput( HDEV* phDevice, SUPPORTED_DEVICE_CHECK pSupportedDeviceCheckFn, unsigned int automaticallyUseGenICamInterface );
|
||||
/// \brief Reads the value of a feature as a string
|
||||
/// \note
|
||||
/// pBuf must be freed by the caller
|
||||
TPROPHANDLING_ERROR getStringValue( HOBJ hObj, char** pBuf, int index );
|
||||
/// \brief Reads the value of a feature as a string
|
||||
/// \note
|
||||
/// pBuf must be freed by the caller
|
||||
TPROPHANDLING_ERROR getValueAsString( HOBJ hObj, const char* pFormat, char** pBuf, int index );
|
||||
void modifyEnumPropertyI( HDRV hDrv, const char* pSettingName, const char* pPropName );
|
||||
/// \brief Shows how to read the translation dictionary of an integer property and returns all the
|
||||
/// integer values in the dictionary.
|
||||
///
|
||||
/// \note
|
||||
/// \a pDictValues must be freed by the caller.
|
||||
TPROPHANDLING_ERROR readTranslationDictValuesI( HOBJ hObj, int** pDictValues, unsigned int* pDictValCnt, unsigned int silent );
|
||||
/// \brief Sets an enumerated integer property to a certain value if this value is supported by
|
||||
/// the property.
|
||||
void conditionalSetPropI( HOBJ hObj, int value, unsigned int silent );
|
||||
|
||||
/// \brief Start the acquisition manually if this was requested(this is to prepare the driver for data capture and tell the device to start streaming data)
|
||||
///
|
||||
/// Whether this is needed or not depends on the property 'AcquisitionStartStopBehaviour' in the list referenced by 'HDEV'.
|
||||
void manuallyStartAcquisitionIfNeeded( HDRV hDrv );
|
||||
/// \brief Stop the acquisition manually if this was requested.
|
||||
///
|
||||
/// Whether this is needed or not depends on the property 'AcquisitionStartStopBehaviour' in the list referenced by 'HDEV'.
|
||||
void manuallyStopAcquisitionIfNeeded( HDRV hDrv );
|
||||
|
||||
#endif // exampleHelper_CH
|
Binary file not shown.
After Width: | Height: | Size: 38 KiB |
@ -0,0 +1,296 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef MV_ICON_XPM
|
||||
#define MV_ICON_XPM MV_ICON_XPM
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static const char* mvIcon_xpm[] = {
|
||||
"32 32 255 2",
|
||||
" c #000100",
|
||||
". c #030005",
|
||||
"+ c #01000D",
|
||||
"@ c #000206",
|
||||
"# c #03011D",
|
||||
"$ c #000407",
|
||||
"% c #000222",
|
||||
"& c #010315",
|
||||
"* c #000319",
|
||||
"= c #000225",
|
||||
"- c #000509",
|
||||
"; c #01070B",
|
||||
"> c #050803",
|
||||
", c #000912",
|
||||
"' c #010929",
|
||||
") c #000B18",
|
||||
"! c #080B07",
|
||||
"~ c #05092E",
|
||||
"{ c #020B2A",
|
||||
"] c #000C29",
|
||||
"^ c #020C3A",
|
||||
"/ c #080D1E",
|
||||
"( c #000E30",
|
||||
"_ c #000F2C",
|
||||
": c #020E36",
|
||||
"< c #0F1315",
|
||||
"[ c #05143B",
|
||||
"} c #001743",
|
||||
"| c #00193A",
|
||||
"1 c #021844",
|
||||
"2 c #071839",
|
||||
"3 c #14181A",
|
||||
"4 c #0B1840",
|
||||
"5 c #001B4C",
|
||||
"6 c #001D48",
|
||||
"7 c #021E55",
|
||||
"8 c #191C1E",
|
||||
"9 c #081E45",
|
||||
"0 c #05213D",
|
||||
"a c #101F32",
|
||||
"b c #062153",
|
||||
"c c #002742",
|
||||
"d c #1C2128",
|
||||
"e c #172231",
|
||||
"f c #00265D",
|
||||
"g c #11253D",
|
||||
"h c #08274E",
|
||||
"i c #1B2338",
|
||||
"j c #002955",
|
||||
"k c #102648",
|
||||
"l c #0F2945",
|
||||
"m c #092B4C",
|
||||
"n c #072B5D",
|
||||
"o c #22282E",
|
||||
"p c #0A2E4A",
|
||||
"q c #0D2D4E",
|
||||
"r c #003061",
|
||||
"s c #013067",
|
||||
"t c #162D3F",
|
||||
"u c #142D4A",
|
||||
"v c #1F2B3A",
|
||||
"w c #073057",
|
||||
"x c #0B2F5C",
|
||||
"y c #113052",
|
||||
"z c #053466",
|
||||
"A c #063651",
|
||||
"B c #00375D",
|
||||
"C c #00366C",
|
||||
"D c #242F3E",
|
||||
"E c #0E345B",
|
||||
"F c #053762",
|
||||
"G c #003970",
|
||||
"H c #0D3758",
|
||||
"I c #12365D",
|
||||
"J c #2E3133",
|
||||
"K c #0D3769",
|
||||
"L c #003B6C",
|
||||
"M c #10366F",
|
||||
"N c #0A3965",
|
||||
"O c #153663",
|
||||
"P c #0E386B",
|
||||
"Q c #2B333E",
|
||||
"R c #043B72",
|
||||
"S c #143860",
|
||||
"T c #23354E",
|
||||
"U c #353337",
|
||||
"V c #113A6C",
|
||||
"W c #073D74",
|
||||
"X c #0B3F59",
|
||||
"Y c #133B6D",
|
||||
"Z c #153A72",
|
||||
"` c #323638",
|
||||
" . c #0E3E64",
|
||||
".. c #35383A",
|
||||
"+. c #2E3949",
|
||||
"@. c #1A4061",
|
||||
"#. c #17406D",
|
||||
"$. c #154269",
|
||||
"%. c #124465",
|
||||
"&. c #264058",
|
||||
"*. c #084963",
|
||||
"=. c #3E3C3F",
|
||||
"-. c #333E59",
|
||||
";. c #2C4260",
|
||||
">. c #294467",
|
||||
",. c #3E4244",
|
||||
"'. c #104E6E",
|
||||
"). c #3E444B",
|
||||
"!. c #44434C",
|
||||
"~. c #00566F",
|
||||
"{. c #175066",
|
||||
"]. c #324867",
|
||||
"^. c #3E4752",
|
||||
"/. c #464755",
|
||||
"(. c #324C70",
|
||||
"_. c #0D5878",
|
||||
":. c #484C4E",
|
||||
"<. c #424D5E",
|
||||
"[. c #37506A",
|
||||
"}. c #474D54",
|
||||
"|. c #00607F",
|
||||
"1. c #165B6F",
|
||||
"2. c #00637B",
|
||||
"3. c #4E504D",
|
||||
"4. c #3E5373",
|
||||
"5. c #475263",
|
||||
"6. c #455369",
|
||||
"7. c #50524F",
|
||||
"8. c #0A6483",
|
||||
"9. c #4E545C",
|
||||
"0. c #3A5877",
|
||||
"a. c #505456",
|
||||
"b. c #126578",
|
||||
"c. c #006B89",
|
||||
"d. c #405A73",
|
||||
"e. c #505965",
|
||||
"f. c #4A5C6C",
|
||||
"g. c #565A5C",
|
||||
"h. c #0A6F81",
|
||||
"i. c #4E5D73",
|
||||
"j. c #515D6E",
|
||||
"k. c #555D6A",
|
||||
"l. c #176F88",
|
||||
"m. c #456282",
|
||||
"n. c #0F7391",
|
||||
"o. c #4F6272",
|
||||
"p. c #5D6163",
|
||||
"q. c #45668B",
|
||||
"r. c #62616A",
|
||||
"s. c #007C99",
|
||||
"t. c #596476",
|
||||
"u. c #52687D",
|
||||
"v. c #0C7D8E",
|
||||
"w. c #516A85",
|
||||
"x. c #61676F",
|
||||
"y. c #576A7A",
|
||||
"z. c #207A8C",
|
||||
"A. c #1A7E96",
|
||||
"B. c #606C7E",
|
||||
"C. c #526F8F",
|
||||
"D. c #008898",
|
||||
"E. c #636C78",
|
||||
"F. c #5F7283",
|
||||
"G. c #68717D",
|
||||
"H. c #25849C",
|
||||
"I. c #188AA1",
|
||||
"J. c #0095A4",
|
||||
"K. c #647A90",
|
||||
"L. c #2F8B97",
|
||||
"M. c #75797C",
|
||||
"N. c #747B82",
|
||||
"O. c #338EA6",
|
||||
"P. c #2497A7",
|
||||
"Q. c #06A1B6",
|
||||
"R. c #6C85A1",
|
||||
"S. c #7F827F",
|
||||
"T. c #199FAE",
|
||||
"U. c #3D96A2",
|
||||
"V. c #3D96AF",
|
||||
"W. c #758899",
|
||||
"X. c #838991",
|
||||
"Y. c #808E94",
|
||||
"Z. c #858F9C",
|
||||
"`. c #579EA6",
|
||||
" + c #589EB3",
|
||||
".+ c #949296",
|
||||
"++ c #8F959D",
|
||||
"@+ c #3BADB6",
|
||||
"#+ c #919598",
|
||||
"$+ c #35AFBE",
|
||||
"%+ c #60A7BB",
|
||||
"&+ c #919AA7",
|
||||
"*+ c #6AA7B1",
|
||||
"=+ c #999C98",
|
||||
"-+ c #92A3AF",
|
||||
";+ c #75ADBE",
|
||||
">+ c #92A6B8",
|
||||
",+ c #57B9C4",
|
||||
"'+ c #7EAFB5",
|
||||
")+ c #85B5C7",
|
||||
"!+ c #A8ADAF",
|
||||
"~+ c #A1AFB6",
|
||||
"{+ c #8DB6BD",
|
||||
"]+ c #73C4CA",
|
||||
"^+ c #6FC5D1",
|
||||
"/+ c #90BCC9",
|
||||
"(+ c #B2B6B9",
|
||||
"_+ c #9FBDC0",
|
||||
":+ c #B1B8C1",
|
||||
"<+ c #9DC1CF",
|
||||
"[+ c #B0BEC5",
|
||||
"}+ c #BABCB9",
|
||||
"|+ c #B4BDCB",
|
||||
"1+ c #B7BEC6",
|
||||
"2+ c #ACC2C7",
|
||||
"3+ c #BABFC1",
|
||||
"4+ c #86CED6",
|
||||
"5+ c #B1C3CF",
|
||||
"6+ c #AAC6D6",
|
||||
"7+ c #BFC6CE",
|
||||
"8+ c #B3CACE",
|
||||
"9+ c #AFCBDB",
|
||||
"0+ c #C4C9CC",
|
||||
"a+ c #C1CDCE",
|
||||
"b+ c #BCCEDA",
|
||||
"c+ c #9BD9E3",
|
||||
"d+ c #9ED9DD",
|
||||
"e+ c #BED0DC",
|
||||
"f+ c #C7CED6",
|
||||
"g+ c #C6CFDE",
|
||||
"h+ c #CBCFD2",
|
||||
"i+ c #C6D3D3",
|
||||
"j+ c #D0D5D7",
|
||||
"k+ c #D2D5D1",
|
||||
"l+ c #D1D8E1",
|
||||
"m+ c #D3D8DA",
|
||||
"n+ c #B0E3E9",
|
||||
"o+ c #D7DBDE",
|
||||
"p+ c #DEE0DD",
|
||||
"q+ c #DCE3EB",
|
||||
"r+ c #C2ECF3",
|
||||
"s+ c #C5ECED",
|
||||
"t+ c #E1E6E9",
|
||||
"u+ c #E8ECEF",
|
||||
"v+ c #D4F3F6",
|
||||
"w+ c #EEF2F5",
|
||||
"x+ c #E2F9FE",
|
||||
"y+ c #F3F8FA",
|
||||
"z+ c #F6F8F5",
|
||||
"A+ c #E8FDFC",
|
||||
"B+ c #F7FBFE",
|
||||
"C+ c #F2FEFF",
|
||||
"D+ c #FBFDFA",
|
||||
"E+ c #FAFFFF",
|
||||
"F+ c #FDFFFC",
|
||||
": : [ 4 9 h w H %.'._.8.l.A.I.P.Q.$+,+^+4+c+n+r+v+x+A+E+F+F+F+F+",
|
||||
"{ ( ( 2 | 0 c p A X *.{.1.b.h.v.v.L.U.`.*+'+{+_+2+8+a+i+j+k+k+j+",
|
||||
"$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ > > > > $ > > > > - > > > ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
"$ $ $ $ $ $ $ $ $ $ > 8 8 ; $ $ ",
|
||||
"$ $ $ $ $ $ $ $ $ ` S.(+p+z+u+j+(+S.U $ $ $ $ $ $ $ $ $ ",
|
||||
"$ $ $ $ $ $ $ 7.(+F+F+F+F+F+F+F+F+F+B+(+3. $ $ $ $ $ $ $ ",
|
||||
"$ $ $ $ $ $ =.}+F+F+F+!+:.8 3 ,.=+z+F+F+F+F+(+.. $ $ $ $ $ $ ",
|
||||
", , , . g.D+F+F+t+,. 3 8 J o+F+F+F+F+B+p. . $ $ $ ",
|
||||
", , }.:.$ t+F+F+j+< p.o+F+F+B+M. ! o+F+F+F+F+w+- J }. $ , ",
|
||||
") !.y+:.d F+F+B+J #+F+F+0+.+0+F+!+ !.F+F+F+F+F+..o B+a. , ",
|
||||
" !.B+F+) ).F+F+#+ x.F+F+p. r.F+9. h+F+F+F+F+r.. w+F+9. ",
|
||||
").w+F+u+) 9.F+D+Q & u+F+++ ^.D !+0+ ++F+F+F+F+x.+ m+F+B+}.",
|
||||
"o+F+F+y+e +.F+t+& <.F+F+D +.E.^.~++ N.o+ ++F+F+F+F+e./ u+F+F+w+",
|
||||
"5.z+F+F+<.a F+j+& G.F+D+a f.X.i N.* h+Y. 3+F+F+F+D+t v B+F+F+k.",
|
||||
"# <.z+F+Z.+ h+t+# y.F+F+t.* [+++/.0+j+& T B+F+F+F+h+& B.F+F+j.* ",
|
||||
"l % 6.D+u+# y.F+0 &.F+F+o+] _ -+1+&+{ ] f+F+F+F+F+F.+ j+F+o.% g ",
|
||||
"u q ( [.z+W.% o+W.= 7+F+F+f+-.= = = -.l+F+F+F+F+o+% u.F+i.{ l u ",
|
||||
"q y y : ].7+;.[.7+[ ].F+F+F+E+:+&+1+F+F+F+F+F+y+;.k |+d.: q y q ",
|
||||
"E E E E 6 @.w.1 m.w.^ K.F+F+F+F+F+F+F+F+F+F+u+4.^ 0.>.6 E E w E ",
|
||||
"F F F F S j x I j $.F 5 C.t+F+F+F+F+F+F+F+|+(.5 I x j S E E E E ",
|
||||
"O O O O O O z F O x F F 5 N R.5+q+q+l+>+q.b b F F O F F F F F F ",
|
||||
"P P P P P P P P P P P L L n 7 r #.#.L f 7 z L K K K K K K K K K ",
|
||||
"V V V V V V V V V V V V V V P C s s C K V V V V V V V V V V V V ",
|
||||
"Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y R R R Y Y Y Y Y Y Y Y Y Y Y Y Y ",
|
||||
"R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R ",
|
||||
"W W W W W W R R R R R R R G G G G G M G G G M M C C M M M M M M ",
|
||||
"W W W W W W W R R R R R R R Z G Z Z G G G M M M M G G G G G G M ",
|
||||
"} 1 6 6 h h w B .%.'._.|.c.n.s.H.O.V. +%+;+)+/+<+6+9+b+e+g+g+g+",
|
||||
"~ ~ : [ 2 k m H X *.~.2.l.z.D.J.T.@+,+]+4+d+n+s+v+A+C+E+F+F+F+F+"};
|
||||
|
||||
#endif // MV_ICON_XPM
|
@ -0,0 +1,3 @@
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400) // is at least VC 2005 compiler?
|
||||
# pragma warning( pop )
|
||||
#endif
|
@ -0,0 +1,7 @@
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400) // is at least VC 2005 compiler?
|
||||
# pragma warning( push )
|
||||
# pragma warning( disable : 4127 ) // 'conditional expression is constant'
|
||||
# pragma warning( disable : 4244 ) // 'conversion from 'Bla' to 'Blub', possible loss of data
|
||||
# pragma warning( disable : 4251 ) // 'class 'Bla' needs to have dll-interface to be used by clients of class 'Blub''
|
||||
# pragma warning( disable : 4800 ) // 'int' : forcing value to bool 'true' or 'false' (performance warning)
|
||||
#endif
|
@ -0,0 +1,409 @@
|
||||
#include "ProxyResolver.h"
|
||||
|
||||
#if _WIN32_WINNT < 0x0602 // This stuff became available with Windows 8
|
||||
# define WINHTTP_CALLBACK_STATUS_GETPROXYFORURL_COMPLETE 0x01000000
|
||||
# define WINHTTP_CALLBACK_FLAG_GETPROXYFORURL_COMPLETE WINHTTP_CALLBACK_STATUS_GETPROXYFORURL_COMPLETE
|
||||
# define API_GET_PROXY_FOR_URL (6)
|
||||
#endif // #if _WIN32_WINNT < _WIN32_WINNT_WIN8
|
||||
|
||||
PFNWINHTTPGETPROXYFORURLEX ProxyResolver::s_pfnWinhttpGetProxyForUrlEx = NULL;
|
||||
PFNWINHTTPFREEPROXYLIST ProxyResolver::s_pfnWinhttpFreeProxyList = NULL;
|
||||
PFNWINHTTPCREATEPROXYRESOLVER ProxyResolver::s_pfnWinhttpCreateProxyResolver = NULL;
|
||||
PFNWINHTTPGETPROXYRESULT ProxyResolver::s_pfnWinhttpGetProxyResult = NULL;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
ProxyResolver::ProxyResolver() : m_fInit( FALSE ), m_fExtendedAPI( FALSE ), m_dwError( ERROR_SUCCESS ), m_hEvent( 0 )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
ZeroMemory( &m_wprProxyResult, sizeof( WINHTTP_PROXY_RESULT ) );
|
||||
ZeroMemory( &m_wpiProxyInfo, sizeof( WINHTTP_PROXY_INFO ) );
|
||||
|
||||
HMODULE hWinhttp = GetModuleHandle( L"winhttp.dll" );
|
||||
if( hWinhttp != NULL )
|
||||
{
|
||||
s_pfnWinhttpGetProxyForUrlEx = ( PFNWINHTTPGETPROXYFORURLEX )GetProcAddress( hWinhttp, "WinHttpGetProxyForUrlEx" );
|
||||
s_pfnWinhttpFreeProxyList = ( PFNWINHTTPFREEPROXYLIST )GetProcAddress( hWinhttp, "WinHttpFreeProxyResult" );
|
||||
s_pfnWinhttpCreateProxyResolver = ( PFNWINHTTPCREATEPROXYRESOLVER )GetProcAddress( hWinhttp, "WinHttpCreateProxyResolver" );
|
||||
s_pfnWinhttpGetProxyResult = ( PFNWINHTTPGETPROXYRESULT )GetProcAddress( hWinhttp, "WinHttpGetProxyResult" );
|
||||
}
|
||||
m_fExtendedAPI = s_pfnWinhttpGetProxyForUrlEx && s_pfnWinhttpFreeProxyList && s_pfnWinhttpCreateProxyResolver && s_pfnWinhttpGetProxyResult;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
ProxyResolver::~ProxyResolver()
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( m_wpiProxyInfo.lpszProxy != NULL )
|
||||
{
|
||||
GlobalFree( m_wpiProxyInfo.lpszProxy );
|
||||
}
|
||||
|
||||
if( m_wpiProxyInfo.lpszProxyBypass != NULL )
|
||||
{
|
||||
GlobalFree( m_wpiProxyInfo.lpszProxyBypass );
|
||||
}
|
||||
|
||||
if( m_fExtendedAPI )
|
||||
{
|
||||
s_pfnWinhttpFreeProxyList( &m_wprProxyResult );
|
||||
}
|
||||
|
||||
if( m_hEvent != NULL )
|
||||
{
|
||||
CloseHandle( m_hEvent );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
BOOL ProxyResolver::IsRecoverableAutoProxyError( _In_ DWORD dwError )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
switch( dwError )
|
||||
{
|
||||
case ERROR_SUCCESS:
|
||||
case ERROR_INVALID_PARAMETER:
|
||||
case ERROR_WINHTTP_AUTO_PROXY_SERVICE_ERROR:
|
||||
case ERROR_WINHTTP_AUTODETECTION_FAILED:
|
||||
case ERROR_WINHTTP_BAD_AUTO_PROXY_SCRIPT:
|
||||
case ERROR_WINHTTP_LOGIN_FAILURE:
|
||||
case ERROR_WINHTTP_OPERATION_CANCELLED:
|
||||
case ERROR_WINHTTP_TIMEOUT:
|
||||
case ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT:
|
||||
case ERROR_WINHTTP_UNRECOGNIZED_SCHEME:
|
||||
return TRUE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
VOID CALLBACK ProxyResolver::GetProxyCallBack( _In_ HINTERNET hResolver, _In_ DWORD_PTR dwContext, _In_ DWORD dwInternetStatus, _In_ PVOID pvStatusInformation, _In_ DWORD /*dwStatusInformationLength*/ )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
ProxyResolver* pProxyResolver = ( ProxyResolver* )dwContext;
|
||||
if( ( dwInternetStatus != WINHTTP_CALLBACK_STATUS_GETPROXYFORURL_COMPLETE &&
|
||||
dwInternetStatus != WINHTTP_CALLBACK_STATUS_REQUEST_ERROR ) ||
|
||||
pProxyResolver == NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( dwInternetStatus == WINHTTP_CALLBACK_STATUS_REQUEST_ERROR )
|
||||
{
|
||||
WINHTTP_ASYNC_RESULT* pAsyncResult = ( WINHTTP_ASYNC_RESULT* )pvStatusInformation;
|
||||
|
||||
if( pAsyncResult->dwResult != API_GET_PROXY_FOR_URL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pProxyResolver->m_dwError = pAsyncResult->dwError;
|
||||
}
|
||||
else if( dwInternetStatus == WINHTTP_CALLBACK_STATUS_GETPROXYFORURL_COMPLETE )
|
||||
{
|
||||
pProxyResolver->m_dwError = s_pfnWinhttpGetProxyResult( hResolver, &pProxyResolver->m_wprProxyResult );
|
||||
}
|
||||
|
||||
if( hResolver != NULL )
|
||||
{
|
||||
WinHttpCloseHandle( hResolver );
|
||||
hResolver = NULL;
|
||||
}
|
||||
|
||||
SetEvent( pProxyResolver->m_hEvent );
|
||||
}
|
||||
|
||||
#define CLOSE_RESOLVER_HANDLE_AND_RETURN_ERROR_CODE(HRESOLVER, ERROR_CODE) \
|
||||
if( HRESOLVER != NULL ) \
|
||||
{ \
|
||||
WinHttpCloseHandle( HRESOLVER ); \
|
||||
} \
|
||||
return ERROR_CODE
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
DWORD ProxyResolver::GetProxyForUrlEx( _In_ HINTERNET hSession, _In_z_ PCWSTR pwszUrl, _In_ WINHTTP_AUTOPROXY_OPTIONS* pAutoProxyOptions )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
// Create proxy resolver handle. It's best to close the handle during call back.
|
||||
HINTERNET hResolver = NULL;
|
||||
DWORD dwError = s_pfnWinhttpCreateProxyResolver( hSession, &hResolver );
|
||||
if( dwError != ERROR_SUCCESS )
|
||||
{
|
||||
CLOSE_RESOLVER_HANDLE_AND_RETURN_ERROR_CODE( hResolver, dwError );
|
||||
}
|
||||
|
||||
// Sets up a callback function that WinHTTP can call as proxy results are resolved.
|
||||
WINHTTP_STATUS_CALLBACK wscCallback = WinHttpSetStatusCallback( hResolver, GetProxyCallBack, WINHTTP_CALLBACK_FLAG_REQUEST_ERROR | WINHTTP_CALLBACK_FLAG_GETPROXYFORURL_COMPLETE, 0 );
|
||||
if( wscCallback == WINHTTP_INVALID_STATUS_CALLBACK )
|
||||
{
|
||||
dwError = GetLastError();
|
||||
CLOSE_RESOLVER_HANDLE_AND_RETURN_ERROR_CODE( hResolver, dwError );
|
||||
}
|
||||
|
||||
// The extended API works in asynchronous mode, therefore wait until the
|
||||
// results are set in the call back function.
|
||||
dwError = s_pfnWinhttpGetProxyForUrlEx( hResolver, pwszUrl, pAutoProxyOptions, ( DWORD_PTR )this );
|
||||
if( dwError != ERROR_IO_PENDING )
|
||||
{
|
||||
CLOSE_RESOLVER_HANDLE_AND_RETURN_ERROR_CODE( hResolver, dwError );
|
||||
}
|
||||
|
||||
// The resolver handle will get closed in the callback and cannot be used any longer.
|
||||
hResolver = NULL;
|
||||
dwError = WaitForSingleObjectEx( m_hEvent, INFINITE, FALSE );
|
||||
if( dwError != WAIT_OBJECT_0 )
|
||||
{
|
||||
return GetLastError();
|
||||
}
|
||||
return m_dwError;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
_Success_( return == ERROR_SUCCESS ) DWORD ProxyResolver::GetProxyForAutoSettings( _In_ HINTERNET hSession, _In_z_ PCWSTR pwszUrl, _In_opt_z_ PCWSTR pwszAutoConfigUrl, _Outptr_result_maybenull_ PWSTR* ppwszProxy, _Outptr_result_maybenull_ PWSTR* ppwszProxyBypass )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
DWORD dwError = ERROR_SUCCESS;
|
||||
WINHTTP_AUTOPROXY_OPTIONS waoOptions = {};
|
||||
WINHTTP_PROXY_INFO wpiProxyInfo = {};
|
||||
|
||||
*ppwszProxy = NULL;
|
||||
*ppwszProxyBypass = NULL;
|
||||
|
||||
if( pwszAutoConfigUrl )
|
||||
{
|
||||
waoOptions.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
|
||||
waoOptions.lpszAutoConfigUrl = pwszAutoConfigUrl;
|
||||
}
|
||||
else
|
||||
{
|
||||
waoOptions.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
|
||||
waoOptions.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A;
|
||||
}
|
||||
|
||||
// First call with no autologon. Autologon prevents the
|
||||
// session (in proc) or autoproxy service (out of proc) from caching
|
||||
// the proxy script. This causes repetitive network traffic, so it is
|
||||
// best not to do autologon unless it is required according to the
|
||||
// result of WinHttpGetProxyForUrl.
|
||||
// This applies to both WinHttpGetProxyForUrl and WinhttpGetProxyForUrlEx.
|
||||
if( m_fExtendedAPI )
|
||||
{
|
||||
m_hEvent = CreateEventEx( NULL, NULL, 0, EVENT_ALL_ACCESS );
|
||||
if( m_hEvent == NULL )
|
||||
{
|
||||
dwError = GetLastError();
|
||||
goto quit;
|
||||
}
|
||||
|
||||
dwError = GetProxyForUrlEx( hSession, pwszUrl, &waoOptions );
|
||||
if( dwError != ERROR_WINHTTP_LOGIN_FAILURE )
|
||||
{
|
||||
// Unless we need to retry with auto-logon exit the function with the
|
||||
// result, on success the proxy list will be stored in m_wprProxyResult
|
||||
// by GetProxyCallBack.
|
||||
goto quit;
|
||||
}
|
||||
|
||||
// Enable autologon if challenged.
|
||||
waoOptions.fAutoLogonIfChallenged = TRUE;
|
||||
dwError = GetProxyForUrlEx( hSession, pwszUrl, &waoOptions );
|
||||
goto quit;
|
||||
}
|
||||
|
||||
if( !WinHttpGetProxyForUrl( hSession, pwszUrl, &waoOptions, &wpiProxyInfo ) )
|
||||
{
|
||||
dwError = GetLastError();
|
||||
if( dwError != ERROR_WINHTTP_LOGIN_FAILURE )
|
||||
{
|
||||
goto quit;
|
||||
}
|
||||
|
||||
// Enable autologon if challenged.
|
||||
dwError = ERROR_SUCCESS;
|
||||
waoOptions.fAutoLogonIfChallenged = TRUE;
|
||||
if( !WinHttpGetProxyForUrl( hSession, pwszUrl, &waoOptions, &wpiProxyInfo ) )
|
||||
{
|
||||
dwError = GetLastError();
|
||||
goto quit;
|
||||
}
|
||||
}
|
||||
|
||||
*ppwszProxy = wpiProxyInfo.lpszProxy;
|
||||
wpiProxyInfo.lpszProxy = NULL;
|
||||
|
||||
*ppwszProxyBypass = wpiProxyInfo.lpszProxyBypass;
|
||||
wpiProxyInfo.lpszProxyBypass = NULL;
|
||||
|
||||
quit:
|
||||
|
||||
if( wpiProxyInfo.lpszProxy )
|
||||
{
|
||||
GlobalFree( wpiProxyInfo.lpszProxy );
|
||||
wpiProxyInfo.lpszProxy = NULL;
|
||||
}
|
||||
|
||||
if( wpiProxyInfo.lpszProxyBypass )
|
||||
{
|
||||
GlobalFree( wpiProxyInfo.lpszProxyBypass );
|
||||
wpiProxyInfo.lpszProxyBypass = NULL;
|
||||
}
|
||||
|
||||
return dwError;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
DWORD ProxyResolver::ResolveProxy( _In_ HINTERNET hSession, _In_z_ PCWSTR pwszUrl )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
DWORD dwError = ERROR_SUCCESS;
|
||||
WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ProxyConfig = {};
|
||||
PWSTR pwszProxy = NULL;
|
||||
PWSTR pwszProxyBypass = NULL;
|
||||
BOOL fFailOverValid = FALSE;
|
||||
|
||||
if( m_fInit )
|
||||
{
|
||||
dwError = ERROR_INVALID_OPERATION;
|
||||
goto quit;
|
||||
}
|
||||
|
||||
if( !WinHttpGetIEProxyConfigForCurrentUser( &ProxyConfig ) )
|
||||
{
|
||||
dwError = GetLastError();
|
||||
if( dwError != ERROR_FILE_NOT_FOUND )
|
||||
{
|
||||
goto quit;
|
||||
}
|
||||
|
||||
// No IE proxy settings found, just do autodetect.
|
||||
ProxyConfig.fAutoDetect = TRUE;
|
||||
dwError = ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
// Begin processing the proxy settings in the following order:
|
||||
// 1) Auto-Detect if configured.
|
||||
// 2) Auto-Config URL if configured.
|
||||
// 3) Static Proxy Settings if configured.
|
||||
//
|
||||
// Once any of these methods succeed in finding a proxy we are finished.
|
||||
// In the event one mechanism fails with an expected error code it is
|
||||
// required to fall back to the next mechanism. If the request fails
|
||||
// after exhausting all detected proxies, there should be no attempt
|
||||
// to discover additional proxies.
|
||||
if( ProxyConfig.fAutoDetect )
|
||||
{
|
||||
fFailOverValid = TRUE;
|
||||
// Detect Proxy Settings.
|
||||
dwError = GetProxyForAutoSettings( hSession, pwszUrl, NULL, &pwszProxy, &pwszProxyBypass );
|
||||
if( dwError == ERROR_SUCCESS )
|
||||
{
|
||||
goto commit;
|
||||
}
|
||||
|
||||
if( !IsRecoverableAutoProxyError( dwError ) )
|
||||
{
|
||||
goto quit;
|
||||
}
|
||||
|
||||
// Fall back to Autoconfig URL or Static settings. An application can
|
||||
// optionally take some action such as logging, or creating a mechanism
|
||||
// to expose multiple error codes in the class.
|
||||
dwError = ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
if( ProxyConfig.lpszAutoConfigUrl )
|
||||
{
|
||||
fFailOverValid = TRUE;
|
||||
// Run autoproxy with AutoConfig URL.
|
||||
dwError = GetProxyForAutoSettings( hSession, pwszUrl, ProxyConfig.lpszAutoConfigUrl, &pwszProxy, &pwszProxyBypass );
|
||||
if( dwError == ERROR_SUCCESS )
|
||||
{
|
||||
goto commit;
|
||||
}
|
||||
|
||||
if( !IsRecoverableAutoProxyError( dwError ) )
|
||||
{
|
||||
goto quit;
|
||||
}
|
||||
|
||||
// Fall back to Static Settings. An application can optionally take some
|
||||
// action such as logging, or creating a mechanism to to expose multiple
|
||||
// error codes in the class.
|
||||
dwError = ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
fFailOverValid = FALSE;
|
||||
// Static Proxy Config. Failover is not valid for static proxy since
|
||||
// it is always either a single proxy or a list containing protocol
|
||||
// specific proxies such as "proxy" or http=httpproxy;https=sslproxy
|
||||
pwszProxy = ProxyConfig.lpszProxy;
|
||||
ProxyConfig.lpszProxy = NULL;
|
||||
|
||||
pwszProxyBypass = ProxyConfig.lpszProxyBypass;
|
||||
ProxyConfig.lpszProxyBypass = NULL;
|
||||
|
||||
commit:
|
||||
|
||||
if( pwszProxy == NULL )
|
||||
{
|
||||
m_wpiProxyInfo.dwAccessType = WINHTTP_ACCESS_TYPE_NO_PROXY;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_wpiProxyInfo.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
|
||||
}
|
||||
|
||||
m_wpiProxyInfo.lpszProxy = pwszProxy;
|
||||
pwszProxy = NULL;
|
||||
|
||||
m_wpiProxyInfo.lpszProxyBypass = pwszProxyBypass;
|
||||
pwszProxyBypass = NULL;
|
||||
|
||||
m_fInit = TRUE;
|
||||
|
||||
quit:
|
||||
|
||||
if( pwszProxy != NULL )
|
||||
{
|
||||
GlobalFree( pwszProxy );
|
||||
pwszProxy = NULL;
|
||||
}
|
||||
|
||||
if( pwszProxyBypass != NULL )
|
||||
{
|
||||
GlobalFree( pwszProxyBypass );
|
||||
pwszProxyBypass = NULL;
|
||||
}
|
||||
|
||||
if( ProxyConfig.lpszAutoConfigUrl != NULL )
|
||||
{
|
||||
GlobalFree( ProxyConfig.lpszAutoConfigUrl );
|
||||
ProxyConfig.lpszAutoConfigUrl = NULL;
|
||||
}
|
||||
|
||||
if( ProxyConfig.lpszProxy != NULL )
|
||||
{
|
||||
GlobalFree( ProxyConfig.lpszProxy );
|
||||
ProxyConfig.lpszProxy = NULL;
|
||||
}
|
||||
|
||||
if( ProxyConfig.lpszProxyBypass != NULL )
|
||||
{
|
||||
GlobalFree( ProxyConfig.lpszProxyBypass );
|
||||
ProxyConfig.lpszProxyBypass = NULL;
|
||||
}
|
||||
|
||||
return dwError;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
const WINHTTP_PROXY_RESULT_ENTRY* ProxyResolver::GetProxySetting( const DWORD index ) const
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( index < m_wprProxyResult.cEntries )
|
||||
{
|
||||
return &m_wprProxyResult.pEntries[index];
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
#include <winhttp.h>
|
||||
|
||||
#if _WIN32_WINNT < 0x0602 // This stuff became available with Windows 8
|
||||
typedef struct _WINHTTP_PROXY_RESULT_ENTRY
|
||||
{
|
||||
BOOL fProxy; // Is this a proxy or DIRECT?
|
||||
BOOL fBypass; // If DIRECT, is it bypassing a proxy (intranet) or is all traffic DIRECT (internet)
|
||||
INTERNET_SCHEME ProxyScheme; // The scheme of the proxy, SOCKS, HTTP (CERN Proxy), HTTPS (SSL through Proxy)
|
||||
PWSTR pwszProxy; // Hostname of the proxy.
|
||||
INTERNET_PORT ProxyPort; // Port of the proxy.
|
||||
} WINHTTP_PROXY_RESULT_ENTRY;
|
||||
|
||||
typedef struct _WINHTTP_PROXY_RESULT
|
||||
{
|
||||
DWORD cEntries;
|
||||
WINHTTP_PROXY_RESULT_ENTRY* pEntries;
|
||||
} WINHTTP_PROXY_RESULT;
|
||||
#endif // #if _WIN32_WINNT < 0x0602
|
||||
|
||||
typedef DWORD ( WINAPI* PFNWINHTTPGETPROXYFORURLEX )( HINTERNET, PCWSTR, WINHTTP_AUTOPROXY_OPTIONS*, DWORD_PTR );
|
||||
typedef DWORD ( WINAPI* PFNWINHTTPFREEPROXYLIST )( WINHTTP_PROXY_RESULT* );
|
||||
typedef DWORD ( WINAPI* PFNWINHTTPCREATEPROXYRESOLVER )( HINTERNET, HINTERNET* );
|
||||
typedef DWORD ( WINAPI* PFNWINHTTPGETPROXYRESULT )( HINTERNET, WINHTTP_PROXY_RESULT* );
|
||||
|
||||
class ProxyResolver
|
||||
{
|
||||
BOOL m_fInit;
|
||||
BOOL m_fExtendedAPI;
|
||||
DWORD m_dwError;
|
||||
HANDLE m_hEvent;
|
||||
WINHTTP_PROXY_INFO m_wpiProxyInfo;
|
||||
WINHTTP_PROXY_RESULT m_wprProxyResult;
|
||||
|
||||
BOOL IsRecoverableAutoProxyError( _In_ DWORD dwError );
|
||||
VOID static CALLBACK GetProxyCallBack( _In_ HINTERNET hResolver, _In_ DWORD_PTR dwContext, _In_ DWORD dwInternetStatus, _In_ PVOID pvStatusInformation, _In_ DWORD dwStatusInformationLength );
|
||||
DWORD GetProxyForUrlEx( _In_ HINTERNET hSession, _In_z_ PCWSTR pwszUrl, _In_ WINHTTP_AUTOPROXY_OPTIONS* pAutoProxyOptions );
|
||||
_Success_( return == ERROR_SUCCESS ) DWORD GetProxyForAutoSettings( _In_ HINTERNET hSession, _In_z_ PCWSTR pwszUrl, _In_opt_z_ PCWSTR pwszAutoConfigUrl, _Outptr_result_maybenull_ PWSTR* ppwszProxy, _Outptr_result_maybenull_ PWSTR* ppwszProxyBypass );
|
||||
|
||||
static PFNWINHTTPGETPROXYFORURLEX s_pfnWinhttpGetProxyForUrlEx;
|
||||
static PFNWINHTTPFREEPROXYLIST s_pfnWinhttpFreeProxyList;
|
||||
static PFNWINHTTPCREATEPROXYRESOLVER s_pfnWinhttpCreateProxyResolver;
|
||||
static PFNWINHTTPGETPROXYRESULT s_pfnWinhttpGetProxyResult;
|
||||
|
||||
public:
|
||||
ProxyResolver();
|
||||
~ProxyResolver();
|
||||
|
||||
DWORD ResolveProxy( _In_ HINTERNET hSession, _In_z_ PCWSTR pwszUrl );
|
||||
const WINHTTP_PROXY_RESULT_ENTRY* GetProxySetting( const DWORD index ) const;
|
||||
};
|
@ -0,0 +1,232 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "../ProxyResolverContext.h"
|
||||
#include "ProxyResolver.h"
|
||||
#include <lmcons.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
//=============================================================================
|
||||
//================= Implementation ProxyResolverContextImpl ===================
|
||||
//=============================================================================
|
||||
//-----------------------------------------------------------------------------
|
||||
struct ProxyResolverContextImpl
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
HINTERNET hProxyResolveSession;
|
||||
ProxyResolver* pProxyResolver;
|
||||
explicit ProxyResolverContextImpl( const wstring& userAgent ) : hProxyResolveSession( 0 ), pProxyResolver( 0 )
|
||||
{
|
||||
hProxyResolveSession = WinHttpOpen( userAgent.c_str(), WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, WINHTTP_FLAG_ASYNC );
|
||||
if( hProxyResolveSession )
|
||||
{
|
||||
pProxyResolver = new ProxyResolver();
|
||||
}
|
||||
}
|
||||
~ProxyResolverContextImpl()
|
||||
{
|
||||
delete pProxyResolver;
|
||||
if( hProxyResolveSession )
|
||||
{
|
||||
WinHttpCloseHandle( hProxyResolveSession );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
//================= Implementation ProxyResolverContext =======================
|
||||
//=============================================================================
|
||||
//-----------------------------------------------------------------------------
|
||||
ProxyResolverContext::ProxyResolverContext( const wstring& userAgent, const wstring& url ) : pImpl_( new ProxyResolverContextImpl( userAgent ) )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( pImpl_->pProxyResolver )
|
||||
{
|
||||
pImpl_->pProxyResolver->ResolveProxy( pImpl_->hProxyResolveSession, url.c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
ProxyResolverContext::~ProxyResolverContext()
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
delete pImpl_;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
wstring ProxyResolverContext::GetProxy( unsigned int index ) const
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
const WINHTTP_PROXY_RESULT_ENTRY* pProxyData = pImpl_->pProxyResolver->GetProxySetting( index );
|
||||
return ( pProxyData && pProxyData->pwszProxy ) ? wstring( pProxyData->pwszProxy ) : wstring();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned int ProxyResolverContext::GetProxyPort( unsigned int index ) const
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
const WINHTTP_PROXY_RESULT_ENTRY* pProxyData = pImpl_->pProxyResolver->GetProxySetting( index );
|
||||
return pProxyData ? pProxyData->ProxyPort : 0;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//================= Implementation helper functions ===========================
|
||||
//=============================================================================
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \brief This function checks the token of the calling thread to see if the caller
|
||||
/// belongs to the Administrators group.
|
||||
/**
|
||||
* \return
|
||||
- true if the caller is an administrator on the local machine.
|
||||
- false otherwise
|
||||
*/
|
||||
bool IsCurrentUserLocalAdministrator( void )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
BOOL fReturn = FALSE;
|
||||
PACL pACL = NULL;
|
||||
PSID psidAdmin = NULL;
|
||||
HANDLE hToken = NULL;
|
||||
HANDLE hImpersonationToken = NULL;
|
||||
PSECURITY_DESCRIPTOR psdAdmin = NULL;
|
||||
|
||||
|
||||
// Determine if the current thread is running as a user that is a member of
|
||||
// the local admins group. To do this, create a security descriptor that
|
||||
// has a DACL which has an ACE that allows only local administrators access.
|
||||
// Then, call AccessCheck with the current thread's token and the security
|
||||
// descriptor. It will say whether the user could access an object if it
|
||||
// had that security descriptor. Note: you do not need to actually create
|
||||
// the object. Just checking access against the security descriptor alone
|
||||
// will be sufficient.
|
||||
const DWORD ACCESS_READ = 1;
|
||||
const DWORD ACCESS_WRITE = 2;
|
||||
|
||||
__try
|
||||
{
|
||||
// AccessCheck() requires an impersonation token. We first get a primary
|
||||
// token and then create a duplicate impersonation token. The
|
||||
// impersonation token is not actually assigned to the thread, but is
|
||||
// used in the call to AccessCheck. Thus, this function itself never
|
||||
// impersonates, but does use the identity of the thread. If the thread
|
||||
// was impersonating already, this function uses that impersonation context.
|
||||
if( !OpenThreadToken( GetCurrentThread(), TOKEN_DUPLICATE | TOKEN_QUERY, TRUE, &hToken ) )
|
||||
{
|
||||
if( GetLastError() != ERROR_NO_TOKEN )
|
||||
{
|
||||
__leave;
|
||||
}
|
||||
|
||||
if( !OpenProcessToken( GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY, &hToken ) )
|
||||
{
|
||||
__leave;
|
||||
}
|
||||
}
|
||||
|
||||
if( !DuplicateToken ( hToken, SecurityImpersonation, &hImpersonationToken ) )
|
||||
{
|
||||
__leave;
|
||||
}
|
||||
|
||||
// Create the binary representation of the well-known SID that
|
||||
// represents the local administrators group. Then create the security
|
||||
// descriptor and DACL with an ACE that allows only local admins access.
|
||||
// After that, perform the access check. This will determine whether
|
||||
// the current user is a local admin.
|
||||
SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY;
|
||||
if( !AllocateAndInitializeSid( &SystemSidAuthority, 2,
|
||||
SECURITY_BUILTIN_DOMAIN_RID,
|
||||
DOMAIN_ALIAS_RID_ADMINS,
|
||||
0, 0, 0, 0, 0, 0, &psidAdmin ) )
|
||||
{
|
||||
__leave;
|
||||
}
|
||||
|
||||
psdAdmin = LocalAlloc( LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH );
|
||||
if( psdAdmin == NULL )
|
||||
{
|
||||
__leave;
|
||||
}
|
||||
|
||||
if( !InitializeSecurityDescriptor( psdAdmin, SECURITY_DESCRIPTOR_REVISION ) )
|
||||
{
|
||||
__leave;
|
||||
}
|
||||
|
||||
// Compute size needed for the ACL.
|
||||
const DWORD dwACLSize = sizeof( ACL ) + sizeof( ACCESS_ALLOWED_ACE ) + GetLengthSid( psidAdmin ) - sizeof( DWORD );
|
||||
pACL = ( PACL )LocalAlloc( LPTR, dwACLSize );
|
||||
if( pACL == NULL )
|
||||
{
|
||||
__leave;
|
||||
}
|
||||
|
||||
if( !InitializeAcl( pACL, dwACLSize, ACL_REVISION2 ) )
|
||||
{
|
||||
__leave;
|
||||
}
|
||||
|
||||
if( !AddAccessAllowedAce( pACL, ACL_REVISION2, ACCESS_READ | ACCESS_WRITE, psidAdmin ) )
|
||||
{
|
||||
__leave;
|
||||
}
|
||||
|
||||
if( !SetSecurityDescriptorDacl( psdAdmin, TRUE, pACL, FALSE ) )
|
||||
{
|
||||
__leave;
|
||||
}
|
||||
|
||||
// AccessCheck validates a security descriptor somewhat; set the group
|
||||
// and owner so that enough of the security descriptor is filled out to
|
||||
// make AccessCheck happy.
|
||||
SetSecurityDescriptorGroup( psdAdmin, psidAdmin, FALSE );
|
||||
SetSecurityDescriptorOwner( psdAdmin, psidAdmin, FALSE );
|
||||
|
||||
if( !IsValidSecurityDescriptor( psdAdmin ) )
|
||||
{
|
||||
__leave;
|
||||
}
|
||||
|
||||
// Initialize GenericMapping structure even though you do not use generic rights.
|
||||
GENERIC_MAPPING GenericMapping;
|
||||
GenericMapping.GenericRead = ACCESS_READ;
|
||||
GenericMapping.GenericWrite = ACCESS_WRITE;
|
||||
GenericMapping.GenericExecute = 0;
|
||||
GenericMapping.GenericAll = ACCESS_READ | ACCESS_WRITE;
|
||||
DWORD dwStructureSize = sizeof( PRIVILEGE_SET );
|
||||
DWORD dwStatus;
|
||||
PRIVILEGE_SET ps;
|
||||
if( !AccessCheck( psdAdmin, hImpersonationToken, ACCESS_READ,
|
||||
&GenericMapping, &ps, &dwStructureSize, &dwStatus,
|
||||
&fReturn ) )
|
||||
{
|
||||
fReturn = FALSE;
|
||||
__leave;
|
||||
}
|
||||
}
|
||||
__finally
|
||||
{
|
||||
if( pACL )
|
||||
{
|
||||
LocalFree( pACL );
|
||||
}
|
||||
if( psdAdmin )
|
||||
{
|
||||
LocalFree( psdAdmin );
|
||||
}
|
||||
if( psidAdmin )
|
||||
{
|
||||
FreeSid( psidAdmin );
|
||||
}
|
||||
if( hImpersonationToken )
|
||||
{
|
||||
CloseHandle ( hImpersonationToken );
|
||||
}
|
||||
if( hToken )
|
||||
{
|
||||
CloseHandle ( hToken );
|
||||
}
|
||||
}
|
||||
|
||||
return fReturn != FALSE;
|
||||
}
|
@ -0,0 +1,651 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef wxAbstractionH
|
||||
#define wxAbstractionH wxAbstractionH
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <apps/Common/Info.h>
|
||||
#include <apps/Common/mvIcon.xpm>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "wxIncludePrologue.h"
|
||||
#include <wx/button.h>
|
||||
#include <wx/combobox.h>
|
||||
#include <wx/config.h>
|
||||
#include <wx/dialog.h>
|
||||
#include <wx/dynlib.h>
|
||||
#include <wx/hyperlink.h>
|
||||
#include <wx/listctrl.h>
|
||||
#include <wx/log.h>
|
||||
#include <wx/notebook.h>
|
||||
#include <wx/settings.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/splash.h>
|
||||
#include <wx/socket.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/string.h>
|
||||
#include <wx/textctrl.h>
|
||||
#include <wx/timer.h>
|
||||
#include <wx/window.h>
|
||||
#include "wxIncludeEpilogue.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
struct ConvertedString : wxString
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
#if wxUSE_UNICODE
|
||||
ConvertedString( const char* s ) :
|
||||
wxString( s, wxConvUTF8 ) {}
|
||||
ConvertedString( const std::string& s ) :
|
||||
wxString( s.c_str(), wxConvUTF8 ) {}
|
||||
ConvertedString( const wxString& s ) :
|
||||
# if wxCHECK_VERSION(2,9,0)
|
||||
wxString( s.mb_str(), wxConvUTF8 ) {}
|
||||
# else
|
||||
wxString( s.c_str(), wxConvUTF8 ) {}
|
||||
# endif
|
||||
#else
|
||||
ConvertedString( const char* s ) :
|
||||
wxString( s ) {}
|
||||
ConvertedString( const std::string& s ) :
|
||||
wxString( s.c_str() ) {}
|
||||
ConvertedString( const wxString& s ) :
|
||||
# if wxCHECK_VERSION(2,9,0)
|
||||
wxString( s.mb_str() ) {}
|
||||
# else
|
||||
wxString( s.c_str() ) {}
|
||||
# endif
|
||||
#endif
|
||||
};
|
||||
|
||||
#if ( wxMINOR_VERSION > 6 ) && ( wxMAJOR_VERSION < 3 ) && !WXWIN_COMPATIBILITY_2_6
|
||||
#include <wx/filedlg.h>
|
||||
enum
|
||||
{
|
||||
wxOPEN = wxFD_OPEN,
|
||||
wxSAVE = wxFD_SAVE,
|
||||
wxOVERWRITE_PROMPT = wxFD_OVERWRITE_PROMPT,
|
||||
wxFILE_MUST_EXIST = wxFD_FILE_MUST_EXIST,
|
||||
wxMULTIPLE = wxFD_MULTIPLE,
|
||||
wxCHANGE_DIR = wxFD_CHANGE_DIR
|
||||
};
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
enum TApplicationColors
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
acRedPastel = ( 200 << 16 ) | ( 200 << 8 ) | 255,
|
||||
acYellowPastel = ( 180 << 16 ) | ( 255 << 8 ) | 255,
|
||||
acBluePastel = ( 255 << 16 ) | ( 220 << 8 ) | 200,
|
||||
acDarkBluePastel = ( 255 << 16 ) | ( 100 << 8 ) | 80,
|
||||
acGreenPastel = ( 200 << 16 ) | ( 255 << 8 ) | 200,
|
||||
acGreyPastel = ( 200 << 16 ) | ( 200 << 8 ) | 200,
|
||||
acDarkGrey = ( 100 << 16 ) | ( 100 << 8 ) | 100
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
//================= Implementation FramePositionStorage =======================
|
||||
//=============================================================================
|
||||
//-----------------------------------------------------------------------------
|
||||
class FramePositionStorage
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
wxWindow* m_pWin;
|
||||
public:
|
||||
FramePositionStorage( wxWindow* pWin ) : m_pWin( pWin ) {}
|
||||
void Save( void ) const
|
||||
{
|
||||
Save( m_pWin );
|
||||
}
|
||||
static void Save( wxWindow* pWin, const wxString& windowName = wxT( "MainFrame" ) )
|
||||
{
|
||||
wxConfigBase* pConfig( wxConfigBase::Get() );
|
||||
int Height, Width, XPos, YPos;
|
||||
pWin->GetSize( &Width, &Height );
|
||||
pWin->GetPosition( &XPos, &YPos );
|
||||
// when we e.g. try to write config stuff on a read-only file system the result can
|
||||
// be an annoying message box. Therefore we switch off logging during the storage operation.
|
||||
wxLogNull logSuspendScope;
|
||||
pConfig->Write( wxString::Format( wxT( "/%s/h" ), windowName.c_str() ), Height );
|
||||
pConfig->Write( wxString::Format( wxT( "/%s/w" ), windowName.c_str() ), Width );
|
||||
pConfig->Write( wxString::Format( wxT( "/%s/x" ), windowName.c_str() ), XPos );
|
||||
pConfig->Write( wxString::Format( wxT( "/%s/y" ), windowName.c_str() ), YPos );
|
||||
if( dynamic_cast<wxTopLevelWindow*>( pWin ) )
|
||||
{
|
||||
pConfig->Write( wxString::Format( wxT( "/%s/maximized" ), windowName.c_str() ), dynamic_cast<wxTopLevelWindow*>( pWin )->IsMaximized() );
|
||||
}
|
||||
pConfig->Flush();
|
||||
}
|
||||
static wxRect Load( const wxRect& defaultDimensions, bool& boMaximized, const wxString& windowName = wxT( "MainFrame" ) )
|
||||
{
|
||||
wxConfigBase* pConfig( wxConfigBase::Get() );
|
||||
wxRect rect;
|
||||
rect.height = pConfig->Read( wxString::Format( wxT( "/%s/h" ), windowName.c_str() ), defaultDimensions.height );
|
||||
rect.width = pConfig->Read( wxString::Format( wxT( "/%s/w" ), windowName.c_str() ), defaultDimensions.width );
|
||||
rect.x = pConfig->Read( wxString::Format( wxT( "/%s/x" ), windowName.c_str() ), defaultDimensions.x );
|
||||
rect.y = pConfig->Read( wxString::Format( wxT( "/%s/y" ), windowName.c_str() ), defaultDimensions.y );
|
||||
boMaximized = pConfig->Read( wxString::Format( wxT( "/%s/maximized" ), windowName.c_str() ), 1l ) != 0;
|
||||
int displayWidth = 0;
|
||||
int displayHeight = 0;
|
||||
wxDisplaySize( &displayWidth, &displayHeight );
|
||||
if( ( rect.x >= displayWidth ) || ( ( rect.x + rect.width ) < 0 ) )
|
||||
{
|
||||
rect.x = 0;
|
||||
}
|
||||
if( ( rect.y >= displayHeight ) || ( ( rect.y + rect.height ) < 0 ) )
|
||||
{
|
||||
rect.y = 0;
|
||||
}
|
||||
return rect;
|
||||
}
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
//================= Implementation SplashScreenScope ==========================
|
||||
//=============================================================================
|
||||
//-----------------------------------------------------------------------------
|
||||
class SplashScreenScope
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
wxSplashScreen* pSplash_;
|
||||
wxStopWatch stopWatch_;
|
||||
public:
|
||||
explicit SplashScreenScope( const wxBitmap& bmp ) : pSplash_( 0 ), stopWatch_()
|
||||
{
|
||||
pSplash_ = new wxSplashScreen( ( wxSystemSettings::GetScreenType() <= wxSYS_SCREEN_SMALL ) ? wxBitmap( mvIcon_xpm ) : bmp, wxSPLASH_CENTRE_ON_SCREEN | wxSPLASH_NO_TIMEOUT, 0, NULL, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER );
|
||||
pSplash_->Update();
|
||||
}
|
||||
virtual ~SplashScreenScope()
|
||||
{
|
||||
const unsigned long startupTime_ms = static_cast<unsigned long>( stopWatch_.Time() );
|
||||
const unsigned long minSplashDisplayTime_ms = 3000;
|
||||
if( startupTime_ms < minSplashDisplayTime_ms )
|
||||
{
|
||||
wxMilliSleep( minSplashDisplayTime_ms - startupTime_ms );
|
||||
}
|
||||
delete pSplash_;
|
||||
}
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
//================= Implementation SocketInitializeScope ======================
|
||||
//=============================================================================
|
||||
//-----------------------------------------------------------------------------
|
||||
class SocketInitializeScope
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
public:
|
||||
explicit SocketInitializeScope()
|
||||
{
|
||||
// This has to be called in order to be able to initialize sockets outside of
|
||||
// the main thread ( http://www.litwindow.com/Knowhow/wxSocket/wxsocket.html )
|
||||
wxSocketBase::Initialize();
|
||||
}
|
||||
~SocketInitializeScope()
|
||||
{
|
||||
// Must apparently be done since we called wxSocketBase::Initialize(),
|
||||
// otherwise memory leaks occur when closing the application.
|
||||
wxSocketBase::Shutdown();
|
||||
}
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
//================= Implementation miscellaneous helper functions =============
|
||||
//=============================================================================
|
||||
//-----------------------------------------------------------------------------
|
||||
inline wxString LoadGenTLProducer( wxDynamicLibrary& lib )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
#ifdef _WIN32
|
||||
const wxString libName( wxT( "mvGenTLProducer.cti" ) );
|
||||
#else
|
||||
const wxString libName( wxT( "libmvGenTLProducer.so" ) );
|
||||
#endif
|
||||
|
||||
const wxString GenTLPathVariable( ( sizeof( void* ) == 8 ) ? wxT( "GENICAM_GENTL64_PATH" ) : wxT( "GENICAM_GENTL32_PATH" ) );
|
||||
#if defined(linux) || defined(__linux) || defined(__linux__)
|
||||
const wxChar PATH_SEPARATOR( wxT( ':' ) );
|
||||
#elif defined(_WIN32) || defined(WIN32) || defined(__WIN32__)
|
||||
const wxChar PATH_SEPARATOR( wxT( ';' ) );
|
||||
#else
|
||||
# error Unsupported target platform
|
||||
#endif
|
||||
wxString GenTLPath;
|
||||
wxArrayString potentialLocations;
|
||||
if( ::wxGetEnv( GenTLPathVariable, &GenTLPath ) )
|
||||
{
|
||||
potentialLocations = wxSplit( GenTLPath, PATH_SEPARATOR );
|
||||
}
|
||||
|
||||
wxString message;
|
||||
// when we e.g. trying to load a shared library that cannot be found the result can
|
||||
// be an annoying message box. Therefore we switch off logging during the load attempts.
|
||||
wxLogNull logSuspendScope;
|
||||
const size_t potentialLocationCount = potentialLocations.Count();
|
||||
for( size_t i = 0; i < potentialLocationCount; i++ )
|
||||
{
|
||||
lib.Load( potentialLocations[i] + wxT( "/" ) + libName, wxDL_VERBATIM );
|
||||
if( lib.IsLoaded() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( !lib.IsLoaded() )
|
||||
{
|
||||
lib.Load( libName, wxDL_VERBATIM );
|
||||
}
|
||||
if( !lib.IsLoaded() )
|
||||
{
|
||||
message = wxString::Format( wxT( "Could not connect to '%s'. Check your installation.\n\n" ), libName.c_str() );
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline void AddSourceInfo( wxWindow* pParent, wxSizer* pParentSizer )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
wxBoxSizer* pSizer = new wxBoxSizer( wxHORIZONTAL );
|
||||
pSizer->Add( new wxStaticText( pParent, wxID_ANY, wxT( "The complete source code belonging to this application can be obtained by contacting " ) ) );
|
||||
pSizer->Add( new wxHyperlinkCtrl( pParent, wxID_ANY, COMPANY_NAME, COMPANY_WEBSITE ) );
|
||||
pParentSizer->Add( pSizer, 0, wxALL | wxALIGN_CENTER, 5 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline void AddSupportInfo( wxWindow* pParent, wxSizer* pParentSizer )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
wxBoxSizer* pSizer = new wxBoxSizer( wxHORIZONTAL );
|
||||
pSizer->Add( new wxStaticText( pParent, wxID_ANY, wxT( "Support contact: " ) ) );
|
||||
pSizer->Add( new wxHyperlinkCtrl( pParent, wxID_ANY, COMPANY_SUPPORT_MAIL, COMPANY_SUPPORT_MAIL ) );
|
||||
pParentSizer->Add( pSizer, 0, wxALL | wxALIGN_CENTER, 5 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline void AddwxWidgetsInfo( wxWindow* pParent, wxSizer* pParentSizer )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
wxBoxSizer* pSizer = new wxBoxSizer( wxHORIZONTAL );
|
||||
pSizer->Add( new wxStaticText( pParent, wxID_ANY, wxT( "This tool has been written using " ) ) );
|
||||
pSizer->Add( new wxHyperlinkCtrl( pParent, wxID_ANY, wxT( "wxWidgets" ), wxT( "http://www.wxwidgets.org" ) ) );
|
||||
pSizer->Add( new wxStaticText( pParent, wxID_ANY, wxString::Format( wxT( " %d.%d.%d." ), wxMAJOR_VERSION, wxMINOR_VERSION, wxRELEASE_NUMBER ) ) );
|
||||
pParentSizer->Add( pSizer, 0, wxALL | wxALIGN_CENTER, 5 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline void AddIconInfo( wxWindow* pParent, wxSizer* pParentSizer )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
wxBoxSizer* pSizer = new wxBoxSizer( wxHORIZONTAL );
|
||||
pSizer->Add( new wxStaticText( pParent, wxID_ANY, wxT( "This tool uses modified icons downloaded from here " ) ) );
|
||||
pSizer->Add( new wxHyperlinkCtrl( pParent, wxID_ANY, wxT( "icons8" ), wxT( "https://icons8.com/" ) ) );
|
||||
pSizer->Add( new wxStaticText( pParent, wxID_ANY, wxT( " and here " ) ) );
|
||||
pSizer->Add( new wxHyperlinkCtrl( pParent, wxID_ANY, wxT( "Freepik" ), wxT( "http://www.freepik.com" ) ) );
|
||||
pSizer->Add( new wxStaticText( pParent, wxID_ANY, wxT( ". The " ) ) );
|
||||
pSizer->Add( new wxHyperlinkCtrl( pParent, wxID_ANY, wxT( "Material Design" ), wxT( "https://material.io/resources/icons/?style=outline" ) ) );
|
||||
pSizer->Add( new wxStaticText( pParent, wxID_ANY, wxT( " icons are published under " ) ) );
|
||||
pSizer->Add( new wxHyperlinkCtrl( pParent, wxID_ANY, wxT( "Apache 2.0 license." ), wxT( "https://www.apache.org/licenses/LICENSE-2.0.html" ) ) );
|
||||
pParentSizer->Add( pSizer, 0, wxALL | wxALIGN_CENTER, 5 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline void AddListControlToAboutNotebook( wxNotebook* pNotebook, const wxString& pageTitle, bool boSelectPage, const wxString& col0, const wxString& col1, const std::vector<std::pair<wxString, wxString> >& v )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
wxListCtrl* pListCtrl = new wxListCtrl( pNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxLC_SINGLE_SEL | wxBORDER_NONE );
|
||||
pListCtrl->InsertColumn( 0, col0 );
|
||||
pListCtrl->InsertColumn( 1, col1 );
|
||||
const unsigned long cnt = static_cast<unsigned long>( v.size() );
|
||||
for( unsigned long i = 0; i < cnt; i++ )
|
||||
{
|
||||
long index = pListCtrl->InsertItem( i, v[i].first, i );
|
||||
pListCtrl->SetItem( index, 1, v[i].second );
|
||||
}
|
||||
for( unsigned int i = 0; i < 2; i++ )
|
||||
{
|
||||
pListCtrl->SetColumnWidth( i, wxLIST_AUTOSIZE );
|
||||
}
|
||||
pNotebook->AddPage( pListCtrl, pageTitle, boSelectPage );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline void AppendPathSeparatorIfNeeded( wxString& path )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( !path.EndsWith( wxT( "/" ) ) && !path.EndsWith( wxT( "\\" ) ) )
|
||||
{
|
||||
path.append( wxT( "/" ) );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline void WriteToTextCtrl( wxTextCtrl* pTextCtrl, const wxString& msg, const wxTextAttr& style = wxTextAttr( *wxBLACK ) )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( pTextCtrl )
|
||||
{
|
||||
// If you want the control to show the last line of text at the bottom, you can add "ScrollLines(1)"
|
||||
// right after the AppendText call. AppendText will ensure the new line is visible, and ScrollLines
|
||||
// will ensure the scroll bar is at the real end of the range, not further.
|
||||
long posBefore = pTextCtrl->GetLastPosition();
|
||||
pTextCtrl->AppendText( msg );
|
||||
long posAfter = pTextCtrl->GetLastPosition();
|
||||
pTextCtrl->SetStyle( posBefore, posAfter, style );
|
||||
pTextCtrl->ScrollLines( 1 );
|
||||
pTextCtrl->ShowPosition( pTextCtrl->GetLastPosition() ); // ensure that this position is really visible
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
struct AboutDialogInformation
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
wxWindow* pParent_;
|
||||
wxString applicationName_;
|
||||
wxString briefDescription_;
|
||||
unsigned int yearOfInitialRelease_;
|
||||
std::vector<std::pair<wxString, wxTextAttr> > usageHints_;
|
||||
std::vector<std::pair<wxString, wxString> > keyboardShortcuts_;
|
||||
std::vector<std::pair<wxString, wxString> > availableCommandLineOptions_;
|
||||
bool boAddIconInfo_;
|
||||
bool boAddExpatInfo_;
|
||||
bool boAddFFmpegInfo_;
|
||||
explicit AboutDialogInformation( wxWindow* pParent = 0 ) : pParent_( pParent ), applicationName_(),
|
||||
briefDescription_(), yearOfInitialRelease_( 2005 ), usageHints_(), keyboardShortcuts_(),
|
||||
availableCommandLineOptions_(), boAddIconInfo_( false ), boAddExpatInfo_( false ), boAddFFmpegInfo_( false ) {}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline void DisplayCommandLineProcessingInformation( wxTextCtrl* pTextCtrl, const wxString& processedCommandLineParameters, const wxString& parserErrors, const wxTextAttr& style )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
WriteToTextCtrl( pTextCtrl, wxT( "\n" ) );
|
||||
WriteToTextCtrl( pTextCtrl, wxT( "Press 'F1' for help.\n" ), style );
|
||||
WriteToTextCtrl( pTextCtrl, wxT( "\n" ) );
|
||||
const wxString none( wxT( "none" ) );
|
||||
WriteToTextCtrl( pTextCtrl, wxString::Format( wxT( "Processed command line parameters: %s\n" ), ( processedCommandLineParameters.length() > 0 ) ? processedCommandLineParameters.c_str() : none.c_str() ), style );
|
||||
WriteToTextCtrl( pTextCtrl, wxT( "\n" ) );
|
||||
if( !parserErrors.IsEmpty() )
|
||||
{
|
||||
WriteToTextCtrl( pTextCtrl, parserErrors, wxTextAttr( *wxRED ) );
|
||||
WriteToTextCtrl( pTextCtrl, wxT( "\n" ) );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline void DisplayCommonAboutDialog( const AboutDialogInformation& info )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
wxBoxSizer* pTopDownSizer;
|
||||
wxDialog dlg( info.pParent_, wxID_ANY, wxString( wxString::Format( wxT( "About %s" ), info.applicationName_.c_str() ) ), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMAXIMIZE_BOX | wxMINIMIZE_BOX );
|
||||
wxIcon icon( mvIcon_xpm );
|
||||
dlg.SetIcon( icon );
|
||||
pTopDownSizer = new wxBoxSizer( wxVERTICAL );
|
||||
wxStaticText* pText = new wxStaticText( &dlg, wxID_ANY, info.briefDescription_ );
|
||||
pTopDownSizer->Add( pText, 0, wxALL | wxALIGN_CENTER, 5 );
|
||||
pText = new wxStaticText( &dlg, wxID_ANY, wxString::Format( wxT( "(C) %u - %s by %s" ), info.yearOfInitialRelease_, CURRENT_YEAR, COMPANY_NAME ) );
|
||||
pTopDownSizer->Add( pText, 0, wxALL | wxALIGN_CENTER, 5 );
|
||||
pText = new wxStaticText( &dlg, wxID_ANY, wxString::Format( wxT( "Version %s" ), VERSION_STRING ) );
|
||||
pTopDownSizer->Add( pText, 0, wxALL | wxALIGN_CENTER, 5 );
|
||||
AddSupportInfo( &dlg, pTopDownSizer );
|
||||
AddwxWidgetsInfo( &dlg, pTopDownSizer );
|
||||
if( info.boAddIconInfo_ )
|
||||
{
|
||||
AddIconInfo( &dlg, pTopDownSizer );
|
||||
}
|
||||
if( info.boAddExpatInfo_ )
|
||||
{
|
||||
pText = new wxStaticText( &dlg, wxID_ANY, wxT( "The expat wrapper class used internally has been written by Descartes Systems Sciences, Inc." ) );
|
||||
pTopDownSizer->Add( pText, 0, wxALL | wxALIGN_CENTER, 5 );
|
||||
}
|
||||
if( info.boAddFFmpegInfo_ )
|
||||
{
|
||||
wxBoxSizer* pSizer = new wxBoxSizer( wxHORIZONTAL );
|
||||
pSizer->Add( new wxStaticText( &dlg, wxID_ANY, wxT( "The video recording functionality of this application requires libraries from the " ) ) );
|
||||
pSizer->Add( new wxHyperlinkCtrl( &dlg, wxID_ANY, wxT( "FFmpeg" ), wxT( "https://www.ffmpeg.org/" ) ) );
|
||||
pSizer->Add( new wxStaticText( &dlg, wxID_ANY, wxT( " project under the LGPLv2.1. These must be installed separately" ) ) );
|
||||
pTopDownSizer->Add( pSizer, 0, wxALL | wxALIGN_CENTER, 5 );
|
||||
}
|
||||
AddSourceInfo( &dlg, pTopDownSizer );
|
||||
wxNotebook* pNotebook = new wxNotebook( &dlg, wxID_ANY, wxDefaultPosition, wxDefaultSize );
|
||||
wxTextCtrl* pUsageHints = new wxTextCtrl( pNotebook, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxBORDER_NONE | wxTE_RICH | wxTE_READONLY );
|
||||
pNotebook->AddPage( pUsageHints, wxT( "Usage Hints" ), true );
|
||||
std::vector<std::pair<wxTextAttr, wxString> >::size_type usageHintStringCount = info.usageHints_.size();
|
||||
for( std::vector<std::pair<wxString, wxTextAttr> >::size_type i = 0; i < usageHintStringCount; i++ )
|
||||
{
|
||||
WriteToTextCtrl( pUsageHints, info.usageHints_[i].first, info.usageHints_[i].second );
|
||||
}
|
||||
pUsageHints->ScrollLines( -( 256 * 256 ) ); // make sure the text control always shows the beginning of the help text
|
||||
if( !info.keyboardShortcuts_.empty() )
|
||||
{
|
||||
AddListControlToAboutNotebook( pNotebook, wxT( "Keyboard Shortcuts" ), false, wxT( "Shortcut" ), wxT( "Command" ), info.keyboardShortcuts_ );
|
||||
}
|
||||
if( !info.availableCommandLineOptions_.empty() )
|
||||
{
|
||||
AddListControlToAboutNotebook( pNotebook, wxT( "Available Command Line Options" ), false, wxT( "Command" ), wxT( "Description" ), info.availableCommandLineOptions_ );
|
||||
}
|
||||
pTopDownSizer->AddSpacer( 10 );
|
||||
pTopDownSizer->Add( pNotebook, wxSizerFlags( 5 ).Expand() );
|
||||
pTopDownSizer->AddSpacer( 10 );
|
||||
wxButton* pBtnOK = new wxButton( &dlg, wxID_OK, wxT( "OK" ) );
|
||||
pBtnOK->SetDefault();
|
||||
pTopDownSizer->Add( pBtnOK, 0, wxALL | wxALIGN_RIGHT, 15 );
|
||||
dlg.SetSizer( pTopDownSizer );
|
||||
dlg.SetSizeHints( 720, 500 );
|
||||
dlg.SetSize( -1, -1, 800, 500 );
|
||||
dlg.ShowModal();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline wxTextAttr GetCommonTextStyle( const bool boBold, const bool boUnderlined, wxTextCtrl*
|
||||
#if wxCHECK_VERSION(2, 9, 5)
|
||||
#else
|
||||
pParent
|
||||
#endif // #if wxCHECK_VERSION(2, 9, 5)
|
||||
)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
wxTextAttr theStyle;
|
||||
#if wxCHECK_VERSION(2, 9, 5)
|
||||
wxFontInfo fontInfo( 10 );
|
||||
if( boBold )
|
||||
{
|
||||
fontInfo.Bold();
|
||||
}
|
||||
if( boUnderlined )
|
||||
{
|
||||
fontInfo.Underlined();
|
||||
}
|
||||
wxFont theFont( fontInfo );
|
||||
#else
|
||||
pParent->GetStyle( pParent->GetLastPosition(), theStyle );
|
||||
wxFont theFont( theStyle.GetFont() );
|
||||
if( boBold )
|
||||
{
|
||||
theFont.SetWeight( wxFONTWEIGHT_BOLD );
|
||||
}
|
||||
theFont.SetPointSize( 10 );
|
||||
if( boUnderlined )
|
||||
{
|
||||
theFont.SetUnderlined( true );
|
||||
}
|
||||
#endif // #if wxCHECK_VERSION(2, 9, 5)
|
||||
theStyle.SetFont( theFont );
|
||||
return theStyle;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline wxTextAttr GetBoldStyle( wxTextCtrl* pParent )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return GetCommonTextStyle( true, false, pParent );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline wxTextAttr GetBoldUnderlinedStyle( wxTextCtrl* pParent )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return GetCommonTextStyle( true, true, pParent );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline wxTextAttr GetDefaultStyle( wxTextCtrl* pParent )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return GetCommonTextStyle( false, false, pParent );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline wxTextAttr GetUnderlinedStyle( wxTextCtrl* pParent )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return GetCommonTextStyle( false, true, pParent );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool IsListOfChoicesEmpty( wxComboBox* pCB )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
#if wxCHECK_VERSION(2, 9, 3)
|
||||
return pCB->IsListEmpty();
|
||||
#else
|
||||
return pCB->IsEmpty();
|
||||
#endif // #if wxCHECK_VERSION(2, 9, 3)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline void StopTimer( wxTimer& timer )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( timer.IsRunning() )
|
||||
{
|
||||
timer.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//===================== Implementation Version helper functions ===============
|
||||
//=============================================================================
|
||||
//-----------------------------------------------------------------------------
|
||||
struct Version
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
long major_;
|
||||
long minor_;
|
||||
long subMinor_;
|
||||
long release_;
|
||||
explicit Version() : major_( -1 ), minor_( -1 ), subMinor_( -1 ), release_( 0 ) {}
|
||||
explicit Version( long ma, long mi, long smi, long re ) : major_( ma ), minor_( mi ), subMinor_( smi ), release_( re ) {}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool operator<( const Version& a, const Version& b )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( a.major_ < b.major_ )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if( a.major_ == b.major_ )
|
||||
{
|
||||
if( a.minor_ < b.minor_ )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if( a.minor_ == b.minor_ )
|
||||
{
|
||||
if( a.subMinor_ < b.subMinor_ )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if( a.subMinor_ == b.subMinor_ )
|
||||
{
|
||||
if( a.release_ < b.release_ )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool operator==( const Version& a, const Version& b )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return ( ( a.major_ == b.major_ ) && ( a.minor_ == b.minor_ ) && ( a.subMinor_ == b.subMinor_ ) && ( a.release_ == b.release_ ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool operator!=( const Version& a, const Version& b )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return ( ( a.major_ != b.major_ ) || ( a.minor_ != b.minor_ ) || ( a.subMinor_ != b.subMinor_ ) || ( a.release_ != b.release_ ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool operator>( const Version& a, const Version& b )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return ( !( a < b ) && !( a == b ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool operator>=( const Version& a, const Version& b )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return ( a > b ) || ( a == b );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool GetNextVersionNumber( wxString& str, long& number )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
wxString numberString = str.BeforeFirst( wxT( '.' ) );
|
||||
str = str.AfterFirst( wxT( '.' ) );
|
||||
return numberString.ToLong( &number );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline Version VersionFromString( const wxString& versionAsString )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
Version version;
|
||||
wxString tmp( versionAsString );
|
||||
GetNextVersionNumber( tmp, version.major_ );
|
||||
if( !tmp.empty() )
|
||||
{
|
||||
GetNextVersionNumber( tmp, version.minor_ );
|
||||
if( !tmp.empty() )
|
||||
{
|
||||
GetNextVersionNumber( tmp, version.subMinor_ );
|
||||
if( !tmp.empty() )
|
||||
{
|
||||
GetNextVersionNumber( tmp, version.release_ );
|
||||
}
|
||||
}
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool IsVersionWithinRange( const Version& version, const Version& minVersion, const Version& maxVersion )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( version < minVersion )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if( version > maxVersion )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // wxAbstractionH
|
@ -0,0 +1,5 @@
|
||||
#if defined(__clang__)
|
||||
# pragma clang diagnostic pop
|
||||
#elif defined(_MSC_VER) && (_MSC_VER >= 1400) // is at least VC 2005 compiler?
|
||||
# pragma warning( pop )
|
||||
#endif
|
@ -0,0 +1,10 @@
|
||||
#if defined(__clang__)
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
# pragma clang diagnostic ignored "-Wunused-local-typedef"
|
||||
#elif defined(_MSC_VER) && (_MSC_VER >= 1400) // is at least VC 2005 compiler?
|
||||
# pragma warning( push )
|
||||
# pragma warning( disable : 4127 ) // 'conditional expression is constant'
|
||||
# pragma warning( disable : 4512 ) // 'class XYZ': assignment operator could not be generated'
|
||||
# pragma warning( disable : 4996 ) // ''function XYZ': was declared deprecated'
|
||||
#endif
|
@ -0,0 +1,9 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef wxIncluderH
|
||||
#define wxIncluderH wxIncluderH
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <apps/Common/wxIncludePrologue.h>
|
||||
#include "wx/wx.h"
|
||||
#include <apps/Common/wxIncludeEpilogue.h>
|
||||
|
||||
#endif // wxIncluderH
|
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
typedef enum _EncMethod {
|
||||
Device = 0,
|
||||
License = 1
|
||||
}EncMethod;
|
||||
|
||||
extern "C" bool GenerateDeviceID(void);
|
||||
extern "C" bool GenerateLicenseData(const char* flag, const char* suffix);
|
||||
extern "C" bool VerifyLicense(void);
|
||||
extern "C" bool AddParaForLicenseData(char* flag, char* suffix);
|
||||
extern "C" bool DeleteParaForLicenseData(char* flag);
|
||||
extern "C" bool AnalysisLicense(const char* flag);
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,105 @@
|
||||
|
||||
#ifndef _MV_ERROR_DEFINE_H_
|
||||
#define _MV_ERROR_DEFINE_H_
|
||||
|
||||
/********************************************************************/
|
||||
/// \~chinese
|
||||
/// \name 正确码定义
|
||||
/// @{
|
||||
/// \~english
|
||||
/// \name Definition of correct code
|
||||
/// @{
|
||||
#define MV_OK 0x00000000 ///< \~chinese 成功,无错误 \~english Successed, no error
|
||||
/// @}
|
||||
|
||||
/********************************************************************/
|
||||
/// \~chinese
|
||||
/// \name 通用错误码定义:范围0x80000000-0x800000FF
|
||||
/// @{
|
||||
/// \~english
|
||||
/// \name Definition of General error code
|
||||
/// @{
|
||||
#define MV_E_HANDLE 0x80000000 ///< \~chinese 错误或无效的句柄 \~english Error or invalid handle
|
||||
#define MV_E_SUPPORT 0x80000001 ///< \~chinese 不支持的功能 \~english Not supported function
|
||||
#define MV_E_BUFOVER 0x80000002 ///< \~chinese 缓存已满 \~english Buffer overflow
|
||||
#define MV_E_CALLORDER 0x80000003 ///< \~chinese 函数调用顺序错误 \~english Function calling order error
|
||||
#define MV_E_PARAMETER 0x80000004 ///< \~chinese 错误的参数 \~english Incorrect parameter
|
||||
#define MV_E_RESOURCE 0x80000006 ///< \~chinese 资源申请失败 \~english Applying resource failed
|
||||
#define MV_E_NODATA 0x80000007 ///< \~chinese 无数据 \~english No data
|
||||
#define MV_E_PRECONDITION 0x80000008 ///< \~chinese 前置条件有误,或运行环境已发生变化 \~english Precondition error, or running environment changed
|
||||
#define MV_E_VERSION 0x80000009 ///< \~chinese 版本不匹配 \~english Version mismatches
|
||||
#define MV_E_NOENOUGH_BUF 0x8000000A ///< \~chinese 传入的内存空间不足 \~english Insufficient memory
|
||||
#define MV_E_ABNORMAL_IMAGE 0x8000000B ///< \~chinese 异常图像,可能是丢包导致图像不完整 \~english Abnormal image, maybe incomplete image because of lost packet
|
||||
#define MV_E_LOAD_LIBRARY 0x8000000C ///< \~chinese 动态导入DLL失败 \~english Load library failed
|
||||
#define MV_E_NOOUTBUF 0x8000000D ///< \~chinese 没有可输出的缓存 \~english No Avaliable Buffer
|
||||
#define MV_E_ENCRYPT 0x8000000E ///< \~chinese 加密错误 \~english Encryption error
|
||||
#define MV_E_UNKNOW 0x800000FF ///< \~chinese 未知的错误 \~english Unknown error
|
||||
/// @}
|
||||
|
||||
/********************************************************************/
|
||||
/// \~chinese
|
||||
/// \name GenICam系列错误:范围0x80000100-0x800001FF
|
||||
/// @{
|
||||
/// \~english
|
||||
/// \name GenICam Series Error Codes: Range from 0x80000100 to 0x800001FF
|
||||
/// @{
|
||||
#define MV_E_GC_GENERIC 0x80000100 ///< \~chinese 通用错误 \~english General error
|
||||
#define MV_E_GC_ARGUMENT 0x80000101 ///< \~chinese 参数非法 \~english Illegal parameters
|
||||
#define MV_E_GC_RANGE 0x80000102 ///< \~chinese 值超出范围 \~english The value is out of range
|
||||
#define MV_E_GC_PROPERTY 0x80000103 ///< \~chinese 属性 \~english Property
|
||||
#define MV_E_GC_RUNTIME 0x80000104 ///< \~chinese 运行环境有问题 \~english Running environment error
|
||||
#define MV_E_GC_LOGICAL 0x80000105 ///< \~chinese 逻辑错误 \~english Logical error
|
||||
#define MV_E_GC_ACCESS 0x80000106 ///< \~chinese 节点访问条件有误 \~english Node accessing condition error
|
||||
#define MV_E_GC_TIMEOUT 0x80000107 ///< \~chinese 超时 \~english Timeout
|
||||
#define MV_E_GC_DYNAMICCAST 0x80000108 ///< \~chinese 转换异常 \~english Transformation exception
|
||||
#define MV_E_GC_UNKNOW 0x800001FF ///< \~chinese GenICam未知错误 \~english GenICam unknown error
|
||||
/// @}
|
||||
|
||||
/********************************************************************/
|
||||
/// \~chinese
|
||||
/// \name GigE_STATUS对应的错误码:范围0x80000200-0x800002FF
|
||||
/// @{
|
||||
/// \~english
|
||||
/// \name GigE_STATUS Error Codes: Range from 0x80000200 to 0x800002FF
|
||||
/// @{
|
||||
#define MV_E_NOT_IMPLEMENTED 0x80000200 ///< \~chinese 命令不被设备支持 \~english The command is not supported by device
|
||||
#define MV_E_INVALID_ADDRESS 0x80000201 ///< \~chinese 访问的目标地址不存在 \~english The target address being accessed does not exist
|
||||
#define MV_E_WRITE_PROTECT 0x80000202 ///< \~chinese 目标地址不可写 \~english The target address is not writable
|
||||
#define MV_E_ACCESS_DENIED 0x80000203 ///< \~chinese 设备无访问权限 \~english No permission
|
||||
#define MV_E_BUSY 0x80000204 ///< \~chinese 设备忙,或网络断开 \~english Device is busy, or network disconnected
|
||||
#define MV_E_PACKET 0x80000205 ///< \~chinese 网络包数据错误 \~english Network data packet error
|
||||
#define MV_E_NETER 0x80000206 ///< \~chinese 网络相关错误 \~english Network error
|
||||
#define MV_E_IP_CONFLICT 0x80000221 ///< \~chinese 设备IP冲突 \~english Device IP conflict
|
||||
/// @}
|
||||
|
||||
/********************************************************************/
|
||||
/// \~chinese
|
||||
/// \name USB_STATUS对应的错误码:范围0x80000300-0x800003FF
|
||||
/// @{
|
||||
/// \~english
|
||||
/// \name USB_STATUS Error Codes: Range from 0x80000300 to 0x800003FF
|
||||
/// @{
|
||||
#define MV_E_USB_READ 0x80000300 ///< \~chinese 读usb出错 \~english Reading USB error
|
||||
#define MV_E_USB_WRITE 0x80000301 ///< \~chinese 写usb出错 \~english Writing USB error
|
||||
#define MV_E_USB_DEVICE 0x80000302 ///< \~chinese 设备异常 \~english Device exception
|
||||
#define MV_E_USB_GENICAM 0x80000303 ///< \~chinese GenICam相关错误 \~english GenICam error
|
||||
#define MV_E_USB_BANDWIDTH 0x80000304 ///< \~chinese 带宽不足 该错误码新增 \~english Insufficient bandwidth, this error code is newly added
|
||||
#define MV_E_USB_DRIVER 0x80000305 ///< \~chinese 驱动不匹配或者未装驱动 \~english Driver mismatch or unmounted drive
|
||||
#define MV_E_USB_UNKNOW 0x800003FF ///< \~chinese USB未知的错误 \~english USB unknown error
|
||||
/// @}
|
||||
|
||||
/********************************************************************/
|
||||
/// \~chinese
|
||||
/// \name 升级时对应的错误码:范围0x80000400-0x800004FF
|
||||
/// @{
|
||||
/// \~english
|
||||
/// \name Upgrade Error Codes: Range from 0x80000400 to 0x800004FF
|
||||
/// @{
|
||||
#define MV_E_UPG_FILE_MISMATCH 0x80000400 ///< \~chinese 升级固件不匹配 \~english Firmware mismatches
|
||||
#define MV_E_UPG_LANGUSGE_MISMATCH 0x80000401 ///< \~chinese 升级固件语言不匹配 \~english Firmware language mismatches
|
||||
#define MV_E_UPG_CONFLICT 0x80000402 ///< \~chinese 升级冲突(设备已经在升级了再次请求升级即返回此错误) \~english Upgrading conflicted (repeated upgrading requests during device upgrade)
|
||||
#define MV_E_UPG_INNER_ERR 0x80000403 ///< \~chinese 升级时设备内部出现错误 \~english Camera internal error during upgrade
|
||||
#define MV_E_UPG_UNKNOW 0x800004FF ///< \~chinese 升级时未知错误 \~english Unknown error during upgrade
|
||||
/// @}
|
||||
|
||||
#endif //_MV_ERROR_DEFINE_H_
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,270 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// (C) Copyright 2005 - 2021 by MATRIX VISION GmbH
|
||||
//
|
||||
// This software is provided by MATRIX VISION GmbH "as is"
|
||||
// and any express or implied warranties, including, but not limited to, the
|
||||
// implied warranties of merchantability and fitness for a particular purpose
|
||||
// are disclaimed.
|
||||
//
|
||||
// In no event shall MATRIX VISION GmbH be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused and
|
||||
// on any theory of liability, whether in contract, strict liability, or tort
|
||||
// (including negligence or otherwise) arising in any way out of the use of
|
||||
// this software, even if advised of the possibility of such damage.
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef MV_CUSTOM_COMMAND_DATA_TYPES_H
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
# define MV_CUSTOM_COMMAND_DATA_TYPES_H MV_CUSTOM_COMMAND_DATA_TYPES_H
|
||||
#endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifdef __GNUC__
|
||||
# define ATTR_PACK __attribute__((packed)) __attribute__ ((aligned (1)))
|
||||
#elif defined _MSC_VER || defined __BORLANDC__
|
||||
# define ATTR_PACK
|
||||
# pragma pack(push, 1) // 1 byte structure alignment
|
||||
#elif !defined(SWIG)
|
||||
# error add your compiler specific structure alignment function here
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
#if defined(MVIMPACT_ACQUIRE_CUSTOM_COMMANDS_H) || defined(DOXYGEN_CPP_DOCUMENTATION)
|
||||
namespace mvIMPACT
|
||||
{
|
||||
namespace acquire
|
||||
{
|
||||
namespace GenICam
|
||||
{
|
||||
#endif // #if defined(MVIMPACT_ACQUIRE_CUSTOM_COMMANDS_H) || defined(DOXYGEN_CPP_DOCUMENTATION)
|
||||
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
# if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
|
||||
typedef __int16 int16_type;
|
||||
typedef unsigned __int16 uint16_type;
|
||||
typedef __int32 int32_type;
|
||||
typedef unsigned __int32 uint32_type;
|
||||
# ifdef __BORLANDC__ // is Borland compiler?
|
||||
# pragma option push -b // force enums to the size of integer
|
||||
# endif // __BORLANDC__
|
||||
# elif defined(linux) || defined(__linux) || defined(__linux__) || defined(__GNUC__)
|
||||
# ifndef WRAP_ANY
|
||||
# include <stdint.h>
|
||||
# endif // #ifndef WRAP_ANY
|
||||
typedef int16_t int16_type;
|
||||
typedef uint16_t uint16_type;
|
||||
typedef int32_t int32_type;
|
||||
typedef uint32_t uint32_type;
|
||||
# else
|
||||
# error "unsupported target environment"
|
||||
# endif // #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
|
||||
#endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \brief Defines valid request transmission modes.
|
||||
/**
|
||||
* Using the custom command interpreter images can requested again from a device
|
||||
* supporting it in different resolutions. This enumeration can be used to define
|
||||
* what/how to transmit the image.
|
||||
*
|
||||
* \since 2.18.0
|
||||
* \ingroup GenICamInterfaceDevice
|
||||
*/
|
||||
enum TRequestTransmissionMode
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
/// \brief Request transmission of an image in full resolution.
|
||||
rtmFullResolution
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \brief Defines valid parameters that can be modified within a sequencer set at runtime.
|
||||
/**
|
||||
* Using the custom command interpreter features controlled by a running sequencer can
|
||||
* be modified while the sequencer is running. This enumeration can be used to define
|
||||
* which parameter shall/can be modified.
|
||||
*
|
||||
* \since 2.18.0
|
||||
* \ingroup GenICamInterfaceDevice
|
||||
*/
|
||||
enum TSequencerSetParameter
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
/// \brief Requests the <tt>CounterDuration[CounterSelector=Counter1]</tt> property to be modified in a user selected sequencer set.
|
||||
sspCounterDuration_Counter1,
|
||||
/// \brief Requests the <tt>CounterDuration[CounterSelector=Counter2]</tt> property to be modified in a user selected sequencer set.
|
||||
sspCounterDuration_Counter2,
|
||||
/// \brief Requests the <tt>CounterDuration[CounterSelector=Counter3]</tt> property to be modified in a user selected sequencer set.
|
||||
sspCounterDuration_Counter3,
|
||||
/// \brief Requests the <tt>CounterDuration[CounterSelector=Counter4]</tt> property to be modified in a user selected sequencer set.
|
||||
sspCounterDuration_Counter4,
|
||||
/// \brief Requests the <tt>CounterDuration[CounterSelector=Counter5]</tt> property to be modified in a user selected sequencer set.
|
||||
sspCounterDuration_Counter5,
|
||||
/// \brief Requests the <tt>CounterDuration[CounterSelector=Counter6]</tt> property to be modified in a user selected sequencer set.
|
||||
sspCounterDuration_Counter6,
|
||||
/// \brief Requests the <tt>CounterDuration[CounterSelector=Counter7]</tt> property to be modified in a user selected sequencer set.
|
||||
sspCounterDuration_Counter7,
|
||||
/// \brief Requests the <tt>CounterDuration[CounterSelector=Counter8]</tt> property to be modified in a user selected sequencer set.
|
||||
sspCounterDuration_Counter8,
|
||||
/// \brief Requests the \c ExposureTime property to be modified in a user selected sequencer set.
|
||||
sspExposureTime,
|
||||
/// \brief Requests the <tt>Gain[GainSelector=AnalogAll]</tt> property to be modified in a user selected sequencer set.
|
||||
sspGain_AnalogAll,
|
||||
/// \brief Requests the <tt>Gain[GainSelector=AnalogRed]</tt> property to be modified in a user selected sequencer set.
|
||||
sspGain_AnalogRed,
|
||||
/// \brief Requests the <tt>Gain[GainSelector=AnalogGreen]</tt> property to be modified in a user selected sequencer set.
|
||||
sspGain_AnalogGreen,
|
||||
/// \brief Requests the <tt>Gain[GainSelector=AnalogBlue]</tt> property to be modified in a user selected sequencer set.
|
||||
sspGain_AnalogBlue,
|
||||
/// \brief Requests the <tt>Gain[GainSelector=AnalogTap1]</tt> property to be modified in a user selected sequencer set.
|
||||
sspGain_AnalogTap1,
|
||||
/// \brief Requests the <tt>Gain[GainSelector=AnalogTap2]</tt> property to be modified in a user selected sequencer set.
|
||||
sspGain_AnalogTap2,
|
||||
/// \brief Requests the <tt>Gain[GainSelector=AnalogTap3]</tt> property to be modified in a user selected sequencer set.
|
||||
sspGain_AnalogTap3,
|
||||
/// \brief Requests the <tt>Gain[GainSelector=AnalogTap4]</tt> property to be modified in a user selected sequencer set.
|
||||
sspGain_AnalogTap4,
|
||||
/// \brief Requests the <tt>OffsetX</tt> property to be modified in a user selected sequencer set.
|
||||
/**
|
||||
* \since 2.34.0, requires firmware version >= 2.35
|
||||
*/
|
||||
sspOffsetX,
|
||||
/// \brief Requests the <tt>OffsetY</tt> property to be modified in a user selected sequencer set.
|
||||
/**
|
||||
* \since 2.34.0, requires firmware version >= 2.35
|
||||
*/
|
||||
sspOffsetY,
|
||||
/// \brief Requests the <tt>Width</tt> property to be modified in a user selected sequencer set.
|
||||
/**
|
||||
* \since 2.36.0, requires firmware version >= 2.36
|
||||
*/
|
||||
sspWidth,
|
||||
/// \brief Requests the <tt>Height</tt> property to be modified in a user selected sequencer set.
|
||||
/**
|
||||
* \since 2.36.0, requires firmware version >= 2.36
|
||||
*/
|
||||
sspHeight
|
||||
};
|
||||
|
||||
#if !defined(DOXYGEN_SHOULD_SKIP_THIS) && !defined(WRAP_ANY)
|
||||
//-----------------------------------------------------------------------------
|
||||
enum TCustomCommand
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
ccSendFrame = 0x0001,
|
||||
ccUpdateSequencerSet = 0x0002,
|
||||
/// Private custom commands start here!
|
||||
ccLAST = 0x8000
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
struct CustomCommandProtocolHeader
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
uint16_type interpreterVersionMajor;
|
||||
uint16_type interpreterVersionMinor;
|
||||
uint16_type totalMessageLength;
|
||||
uint16_type request_id;
|
||||
} ATTR_PACK;
|
||||
|
||||
#define VARS_SFCPacketHeader \
|
||||
uint16_type command; \
|
||||
uint16_type messageLength;
|
||||
|
||||
#define VARS_SFCPacketUpdateSequencerSet \
|
||||
uint16_type sequencerSet; \
|
||||
uint16_type sequencerSetParameter;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
struct CustomCommandHeader
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
VARS_SFCPacketHeader
|
||||
} ATTR_PACK;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
struct CustomCommandSendFrame
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
VARS_SFCPacketHeader
|
||||
uint32_type offsetX;
|
||||
uint32_type offsetY;
|
||||
uint32_type width;
|
||||
uint32_type height;
|
||||
uint32_type timestamp_high;
|
||||
uint32_type timestamp_low;
|
||||
uint32_type identifier;
|
||||
} ATTR_PACK;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
struct CustomCommandUpdateSequencerSet
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
VARS_SFCPacketHeader
|
||||
VARS_SFCPacketUpdateSequencerSet
|
||||
} ATTR_PACK;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
struct CustomCommandUpdateSequencerSetI64
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
VARS_SFCPacketHeader
|
||||
VARS_SFCPacketUpdateSequencerSet
|
||||
int32_type value_high;
|
||||
int32_type value_low;
|
||||
} ATTR_PACK;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
struct CustomCommandUpdateSequencerSetF
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
VARS_SFCPacketHeader
|
||||
VARS_SFCPacketUpdateSequencerSet
|
||||
char data[8];
|
||||
} ATTR_PACK;
|
||||
|
||||
typedef enum TRequestTransmissionMode TRequestTransmissionMode;
|
||||
typedef enum TSequencerSetParameter TSequencerSetParameter;
|
||||
typedef enum TCustomCommand TCustomCommand;
|
||||
typedef struct CustomCommandProtocolHeader CustomCommandProtocolHeader;
|
||||
typedef struct CustomCommandHeader CustomCommandHeader;
|
||||
typedef struct CustomCommandSendFrame CustomCommandSendFrame;
|
||||
typedef struct CustomCommandUpdateSequencerSet CustomCommandUpdateSequencerSet;
|
||||
typedef struct CustomCommandUpdateSequencerSetI64 CustomCommandUpdateSequencerSetI64;
|
||||
typedef struct CustomCommandUpdateSequencerSetF CustomCommandUpdateSequencerSetF;
|
||||
#endif // #if !defined(DOXYGEN_SHOULD_SKIP_THIS) && !defined(WRAP_ANY)
|
||||
|
||||
// restore Borland compiler switch 'force enums to the size of integer'
|
||||
#if !defined(DOXYGEN_SHOULD_SKIP_THIS) && !defined(WRAP_ANY)
|
||||
# ifdef _WIN32
|
||||
# ifdef __BORLANDC__
|
||||
# pragma option pop
|
||||
# endif // __BORLANDC__
|
||||
# endif // _WIN32
|
||||
#endif // #if !defined(DOXYGEN_SHOULD_SKIP_THIS) && !defined(WRAP_ANY)
|
||||
|
||||
#if defined(MVIMPACT_ACQUIRE_CUSTOM_COMMANDS_H) || defined(DOXYGEN_CPP_DOCUMENTATION)
|
||||
} // namespace GenICam
|
||||
} // namespace acquire
|
||||
} // namespace mvIMPACT
|
||||
#endif // #if defined(MVIMPACT_ACQUIRE_CUSTOM_COMMANDS_H) || defined(DOXYGEN_CPP_DOCUMENTATION)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#ifdef __GNUC__
|
||||
# undef ATTR_PACK
|
||||
#elif defined _MSC_VER || defined __BORLANDC__
|
||||
# undef ATTR_PACK
|
||||
# pragma pack(pop) // restore previous structure alignment
|
||||
#elif !defined(SWIG)
|
||||
# error restore your compiler specific structure alignment here if necessary
|
||||
#endif
|
||||
|
||||
#endif /*MV_CUSTOM_COMMAND_DATA_TYPES_H*/
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,78 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// (C) Copyright 2005 - 2021 by MATRIX VISION GmbH
|
||||
//
|
||||
// This software is provided by MATRIX VISION GmbH "as is"
|
||||
// and any express or implied warranties, including, but not limited to, the
|
||||
// implied warranties of merchantability and fitness for a particular purpose
|
||||
// are disclaimed.
|
||||
//
|
||||
// In no event shall MATRIX VISION GmbH be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused and
|
||||
// on any theory of liability, whether in contract, strict liability, or tort
|
||||
// (including negligence or otherwise) arising in any way out of the use of
|
||||
// this software, even if advised of the possibility of such damage.
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef mvVersionInfoH
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
# define mvVersionInfoH mvVersionInfoH
|
||||
#endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if !defined(mvDriverBaseEnumsH) && !defined(SWIG)
|
||||
# error "This file must NOT be included directly! Include mvDeviceManager.h(C-API) or mvIMPACT_acquire.h(C++ API) instead"
|
||||
#endif // #if !defined(mvDriverBaseEnumsH) && !defined(SWIG)
|
||||
|
||||
/// \brief Returns the major version number of the current mvIMPACT Acquire release.
|
||||
/**
|
||||
* \returns The major version number of mvIMPACT Acquire
|
||||
*/
|
||||
#define MVIMPACT_ACQUIRE_MAJOR_VERSION 2
|
||||
|
||||
/// \brief Returns the minor version number of the current mvIMPACT Acquire release.
|
||||
/**
|
||||
* \returns The minor version number of mvIMPACT Acquire
|
||||
*/
|
||||
#define MVIMPACT_ACQUIRE_MINOR_VERSION 43
|
||||
|
||||
/// \brief Returns the release version number of the current mvIMPACT Acquire release.
|
||||
/**
|
||||
* \returns The release version number of mvIMPACT Acquire
|
||||
*/
|
||||
#define MVIMPACT_ACQUIRE_RELEASE_VERSION 0
|
||||
|
||||
/// \brief Returns the build version number of the current mvIMPACT Acquire release.
|
||||
/**
|
||||
* \returns The build version number of mvIMPACT Acquire
|
||||
*/
|
||||
#define MVIMPACT_ACQUIRE_BUILD_VERSION 3180
|
||||
|
||||
/// \brief Returns the full version number of the current mvIMPACT Acquire release as a string ("2.43.0.3180").
|
||||
/**
|
||||
* \returns The full version string of mvIMPACT Acquire
|
||||
*/
|
||||
#define MVIMPACT_ACQUIRE_VERSION_STRING "2.43.0.3180"
|
||||
|
||||
/// \brief This is a macro which evaluates to true if the current mvIMPACT Acquire version is at least major.minor.release.
|
||||
/**
|
||||
* For example, to test if the program will be compiled with mvIMPACT Acquire 2.0 or higher, the following can be done:
|
||||
*
|
||||
* \code
|
||||
* HDISP hDisp = getDisplayHandleFromSomewhere();
|
||||
* #if MVIMPACT_ACQUIRE_CHECK_VERSION(2, 0, 0)
|
||||
* mvDispWindowDestroy( hDisp );
|
||||
* #else // replacement code for old version
|
||||
* mvDestroyImageWindow( hDisp );
|
||||
* #endif
|
||||
* \endcode
|
||||
*
|
||||
* \since 2.0.0
|
||||
*/
|
||||
#define MVIMPACT_ACQUIRE_CHECK_VERSION(MAJOR, MINOR, RELEASE) \
|
||||
(MVIMPACT_ACQUIRE_MAJOR_VERSION > (MAJOR) || \
|
||||
(MVIMPACT_ACQUIRE_MAJOR_VERSION == (MAJOR) && MVIMPACT_ACQUIRE_MINOR_VERSION > (MINOR)) || \
|
||||
(MVIMPACT_ACQUIRE_MAJOR_VERSION == (MAJOR) && MVIMPACT_ACQUIRE_MINOR_VERSION == (MINOR) && MVIMPACT_ACQUIRE_RELEASE_VERSION >= (RELEASE)))
|
||||
|
||||
#endif // mvVersionInfoH
|
@ -0,0 +1,40 @@
|
||||
#include "CommonGUIFunctions.h"
|
||||
|
||||
#include "wxIncludePrologue.h"
|
||||
#include <wx/progdlg.h>
|
||||
#include "wxIncludeEpilogue.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void RunThreadAndShowProgress( wxThread* pThread, wxProgressDialog* pDlg, unsigned long threadInterval_ms, int maxExecutionTime_ms )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
pThread->Create();
|
||||
pThread->Run();
|
||||
while( pThread->IsRunning() )
|
||||
{
|
||||
wxMilliSleep( threadInterval_ms );
|
||||
if( pDlg )
|
||||
{
|
||||
pDlg->Pulse();
|
||||
}
|
||||
}
|
||||
pThread->Wait();
|
||||
if( pDlg )
|
||||
{
|
||||
pDlg->Update( maxExecutionTime_ms );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void UpdateDeviceListWithProgressMessage( wxWindow* pParent, const mvIMPACT::acquire::DeviceManager& devMgr )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
static const int MAX_TIME_MS = 10000;
|
||||
wxProgressDialog progressDialog( wxT( "Scanning For Drivers, Interfaces and Devices" ),
|
||||
wxT( "Scanning for drivers, interfaces and devices...\n\nThis dialog will disappear automatically once this operation completes!" ),
|
||||
MAX_TIME_MS, // range
|
||||
pParent,
|
||||
wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_ELAPSED_TIME );
|
||||
UpdateDeviceListThread thread( devMgr );
|
||||
RunThreadAndShowProgress( &thread, &progressDialog, 100, MAX_TIME_MS );
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef CommonGUIFunctionsH
|
||||
#define CommonGUIFunctionsH CommonGUIFunctionsH
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <mvIMPACT_CPP/mvIMPACT_acquire.h>
|
||||
|
||||
#include "wxIncludePrologue.h"
|
||||
#include <wx/thread.h>
|
||||
#include "wxIncludeEpilogue.h"
|
||||
|
||||
class wxProgressDialog;
|
||||
class wxWindow;
|
||||
|
||||
void RunThreadAndShowProgress( wxThread* pThread, wxProgressDialog* pDlg, unsigned long threadInterval_ms, int maxExecutionTime_ms );
|
||||
|
||||
//=============================================================================
|
||||
//================= Implementation UpdateDeviceListThread =====================
|
||||
//=============================================================================
|
||||
//------------------------------------------------------------------------------
|
||||
class UpdateDeviceListThread : public wxThread
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
const mvIMPACT::acquire::DeviceManager& devMgr_;
|
||||
protected:
|
||||
void* Entry( void )
|
||||
{
|
||||
devMgr_.updateDeviceList();
|
||||
return 0;
|
||||
}
|
||||
public:
|
||||
explicit UpdateDeviceListThread( const mvIMPACT::acquire::DeviceManager& devMgr ) : wxThread( wxTHREAD_JOINABLE ),
|
||||
devMgr_( devMgr ) {}
|
||||
};
|
||||
|
||||
void UpdateDeviceListWithProgressMessage( wxWindow* pParent, const mvIMPACT::acquire::DeviceManager& devMgr );
|
||||
|
||||
#endif // CommonGUIFunctionsH
|
@ -0,0 +1,12 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef InfoH
|
||||
#define InfoH InfoH
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#define COMPANY_NAME wxT("MATRIX VISION GmbH")
|
||||
#define COMPANY_WEBSITE wxT("www.matrix-vision.com")
|
||||
#define COMPANY_SUPPORT_MAIL wxT("mailto:support@matrix-vision.com")
|
||||
#define CURRENT_YEAR wxT("2021")
|
||||
#define VERSION_STRING wxT("2.43.0.3180")
|
||||
|
||||
#endif // InfoH
|
@ -0,0 +1,22 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef ProxyResolverContextH
|
||||
#define ProxyResolverContextH ProxyResolverContextH
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <string>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class ProxyResolverContext
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
struct ProxyResolverContextImpl* pImpl_;
|
||||
public:
|
||||
explicit ProxyResolverContext( const std::wstring& userAgent = std::wstring(), const std::wstring& url = std::wstring() );
|
||||
~ProxyResolverContext();
|
||||
|
||||
std::wstring GetProxy( unsigned int index ) const;
|
||||
unsigned int GetProxyPort( unsigned int index ) const;
|
||||
};
|
||||
|
||||
bool IsCurrentUserLocalAdministrator( void );
|
||||
|
||||
#endif // ProxyResolverContextH
|
@ -0,0 +1,39 @@
|
||||
//----------------------------------------------------------------------------------------
|
||||
#ifndef aviexceptionH
|
||||
#define aviexceptionH aviexceptionH
|
||||
//----------------------------------------------------------------------------------------
|
||||
#include <string>
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
class AVIException
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
public:
|
||||
virtual const char* what() const = 0;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
class AEUnsupportedCodec : public AVIException
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
public:
|
||||
const char* what() const
|
||||
{
|
||||
return "Unsupported codec";
|
||||
}
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
class AVIWrapperException : public AVIException
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
std::string m_errorString;
|
||||
public:
|
||||
AVIWrapperException( const char* pError ) : m_errorString( pError ) {}
|
||||
const char* what() const
|
||||
{
|
||||
return m_errorString.c_str();
|
||||
}
|
||||
};
|
||||
|
||||
#endif // aviexceptionH
|
@ -0,0 +1,173 @@
|
||||
//----------------------------------------------------------------------------------------
|
||||
#include "avihelper.h"
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
using namespace std;
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
/*!
|
||||
\brief Builds an error string from an AVI error code.
|
||||
\param error The error code to be converted.
|
||||
|
||||
Helper function to convert an AVI error code into a string.
|
||||
*/
|
||||
string AVIErrorToString( HRESULT error )
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
string errormsg( "AVI error '" );
|
||||
switch( error )
|
||||
{
|
||||
case AVIERR_BADFLAGS :
|
||||
errormsg.append( "AVIERR_BADFLAGS" );
|
||||
break;
|
||||
case AVIERR_BADFORMAT :
|
||||
errormsg.append( "AVIERR_BADFORMAT" );
|
||||
break;
|
||||
case AVIERR_BADHANDLE :
|
||||
errormsg.append( "AVIERR_BADHANDLE" );
|
||||
break;
|
||||
case AVIERR_BADPARAM :
|
||||
errormsg.append( "AVIERR_BADPARAM" );
|
||||
break;
|
||||
case AVIERR_BADSIZE :
|
||||
errormsg.append( "AVIERR_BADSIZE" );
|
||||
break;
|
||||
case AVIERR_BUFFERTOOSMALL :
|
||||
errormsg.append( "AVIERR_BUFFERTOOSMALL" );
|
||||
break;
|
||||
case AVIERR_CANTCOMPRESS :
|
||||
errormsg.append( "AVIERR_CANTCOMPRESS" );
|
||||
break;
|
||||
case AVIERR_COMPRESSOR :
|
||||
errormsg.append( "AVIERR_COMPRESSOR" );
|
||||
break;
|
||||
case AVIERR_NOCOMPRESSOR :
|
||||
errormsg.append( "AVIERR_NOCOMPRESSOR" );
|
||||
break;
|
||||
case AVIERR_NODATA :
|
||||
errormsg.append( "AVIERR_NODATA" );
|
||||
break;
|
||||
case AVIERR_FILEOPEN :
|
||||
errormsg.append( "AVIERR_FILEOPEN" );
|
||||
break;
|
||||
case AVIERR_FILEREAD :
|
||||
errormsg.append( "AVIERR_FILEREAD" );
|
||||
break;
|
||||
case AVIERR_FILEWRITE :
|
||||
errormsg.append( "AVIERR_FILEWRITE" );
|
||||
break;
|
||||
case AVIERR_INTERNAL :
|
||||
errormsg.append( "AVIERR_INTERNAL" );
|
||||
break;
|
||||
case AVIERR_MEMORY :
|
||||
errormsg.append( "AVIERR_MEMORY" );
|
||||
break;
|
||||
case AVIERR_READONLY :
|
||||
errormsg.append( "AVIERR_READONLY" );
|
||||
break;
|
||||
case AVIERR_UNSUPPORTED :
|
||||
errormsg.append( "AVIERR_UNSUPPORTED" );
|
||||
break;
|
||||
case AVIERR_USERABORT :
|
||||
errormsg.append( "AVIERR_USERABORT" );
|
||||
break;
|
||||
case REGDB_E_CLASSNOTREG :
|
||||
errormsg.append( "REGDB_E_CLASSNOTREG" );
|
||||
break;
|
||||
default:
|
||||
return "Unrecognized error";
|
||||
}
|
||||
return( errormsg.append( "' occurred" ) );
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
/*!
|
||||
\brief Builds a test image.
|
||||
\param pData Pointer to the memory in which to build the test image.
|
||||
\param width The width of the test image.
|
||||
\param height The height of the test image.
|
||||
\param bytespp The bytes per pixel of the test image.
|
||||
|
||||
This function is only needed for testing purposes. It builds a moving vertical
|
||||
grey ramp in the memory pointed to by \e pData. In each new image will move one
|
||||
pixel to the right in order to simulate movement.
|
||||
*/
|
||||
void BuildTestImage( unsigned char* pData, int width, int height, int bytespp )
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
static int count = 0;
|
||||
unsigned char* p = pData;
|
||||
|
||||
for( int i = 0; i < height; i++ )
|
||||
{
|
||||
for( int j = 0; j < width; j++ )
|
||||
{
|
||||
for( int x = 0; x < bytespp; x++ )
|
||||
{
|
||||
p[x] = static_cast<unsigned char>( j + count % 256 );
|
||||
}
|
||||
p += bytespp;
|
||||
}
|
||||
}
|
||||
++count;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
/*!
|
||||
\brief Convertes a user selected codec into the corresponding 4 character code
|
||||
\param codec The codec to be converted.
|
||||
*/
|
||||
DWORD CodecToFourccCode( CODEC_T codec )
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
switch( codec )
|
||||
{
|
||||
case codecNoCompression:
|
||||
return mmioFOURCC( 'D', 'I', 'B', ' ' );
|
||||
case codecMorganMjpg:
|
||||
return mmioFOURCC( 'M', 'J', 'P', 'G' );
|
||||
case codecMorganMjpg2000:
|
||||
return mmioFOURCC( 'M', 'J', '2', 'C' );
|
||||
case codecIntelJpg:
|
||||
return mmioFOURCC( 'M', 'J', 'P', 'G' );
|
||||
case codecHuffYUV:
|
||||
return mmioFOURCC( 'H', 'F', 'Y', 'U' );
|
||||
case codecDivx5:
|
||||
return mmioFOURCC( 'd', 'i', 'v', 'x' );
|
||||
case codec3ivx:
|
||||
return mmioFOURCC( '3', 'i', 'v', '2' );
|
||||
case codecMjpg2:
|
||||
return mmioFOURCC( 'e', 'm', '2', 'v' );
|
||||
case codecPicVideoWavelet:
|
||||
return mmioFOURCC( 'p', 'v', 'w', '2' );
|
||||
case codecPicVideoMjpg:
|
||||
return mmioFOURCC( 'm', 'j', 'p', 'x' );
|
||||
case codecPicVideoLossLessJpg:
|
||||
return mmioFOURCC( 'p', 'i', 'm', 'j' );
|
||||
case codecMSVideo:
|
||||
return mmioFOURCC( 'm', 's', 'v', 'c' );
|
||||
case codecMSRle:
|
||||
return mmioFOURCC( 'm', 'r', 'l', 'e' );
|
||||
case codecMSH263:
|
||||
return mmioFOURCC( 'm', '2', '6', '3' );
|
||||
case codecMSH261:
|
||||
return mmioFOURCC( 'm', '2', '6', '1' );
|
||||
case codecIntelVidR32:
|
||||
return mmioFOURCC( 'i', 'v', '3', '2' );
|
||||
case codecIntelIndeo510:
|
||||
return mmioFOURCC( 'i', 'v', '5', '0' );
|
||||
case codecDivxMjpg4lm:
|
||||
return mmioFOURCC( 'd', 'i', 'v', '3' );
|
||||
case codecDivxMjpg4fm:
|
||||
return mmioFOURCC( 'd', 'i', 'v', '4' );
|
||||
case codecCinepack:
|
||||
return mmioFOURCC( 'c', 'v', 'i', 'd' );
|
||||
case codecMSMpeg4:
|
||||
return mmioFOURCC( 'm', 'p', 'g', '4' );
|
||||
case codecMax:
|
||||
return mmioFOURCC( 'D', 'I', 'B', ' ' );
|
||||
default:
|
||||
break;
|
||||
}
|
||||
throw AEUnsupportedCodec();
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
//----------------------------------------------------------------------------------------
|
||||
#ifndef avihelperH
|
||||
#define avihelperH avihelperH
|
||||
//----------------------------------------------------------------------------------------
|
||||
#include <windows.h>
|
||||
#include <Vfw.h>
|
||||
#include "aviexception.h"
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\brief The codecs recognized by the \b AVIWrapper class.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
codecNoCompression = 0,
|
||||
codecMorganMjpg = 1,
|
||||
codecMorganMjpg2000 = 2,
|
||||
codecIntelJpg = 3,
|
||||
codecHuffYUV = 4,
|
||||
codecDivx5 = 5,
|
||||
codec3ivx = 6,
|
||||
codecMjpg2 = 7,
|
||||
codecPicVideoWavelet = 8,
|
||||
codecPicVideoMjpg = 9,
|
||||
codecPicVideoLossLessJpg = 10,
|
||||
codecMSVideo = 11,
|
||||
codecMSRle = 12,
|
||||
codecMSH263 = 13,
|
||||
codecMSH261 = 14,
|
||||
codecIntelVidR32 = 15,
|
||||
codecIntelIndeo510 = 16,
|
||||
codecDivxMjpg4lm = 17,
|
||||
codecDivxMjpg4fm = 18,
|
||||
codecCinepack = 19,
|
||||
codecMSMpeg4 = 20,
|
||||
codecMax
|
||||
} CODEC_T;
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
std::string AVIErrorToString( HRESULT error );
|
||||
void BuildTestImage( unsigned char* pData, int width, int height, int bytespp );
|
||||
DWORD CodecToFourccCode( CODEC_T codec );
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
#endif // avihelperH
|
@ -0,0 +1,293 @@
|
||||
//----------------------------------------------------------------------------------------
|
||||
#include "aviwrapper.h"
|
||||
#include <cassert>
|
||||
#include <common/crt/mvstring.h>
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\class AVIWrapper
|
||||
\brief Provides an easy way to create and use *.avi-files.
|
||||
|
||||
This class is meant to provide easy access to the AVI file functions. It can be used to generate
|
||||
an AVI stream with only a few lines of code.
|
||||
|
||||
Three general methods are supported:
|
||||
|
||||
- Creation of an AVI stream using the standard Windows compression options dialog (interactively)
|
||||
- Creation of an AVI stream specifying a codec handler, quality settings and image dimensions
|
||||
(not interactively)
|
||||
- Creation of an AVI stream from images which are already in jpeg format.
|
||||
*/
|
||||
|
||||
unsigned int AVIWrapper::m_usageCount = 0;
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
/*!
|
||||
\brief Constructs a new \b AVIWrapper object.
|
||||
\param filename The filename of the AVI file to be created or \e 0 if no file shall be
|
||||
created.
|
||||
\param mode The access mode for this file.
|
||||
|
||||
Opens and creates an AVI file in the mode specified by the \e mode parameter if
|
||||
a filename has been specified. See MSDN for details about the available modes.
|
||||
*/
|
||||
AVIWrapper::AVIWrapper( const char* pFilename /* = 0 */, UINT mode /* = OF_READ */ ) :
|
||||
m_AVIStreamFrameCounter( 0 ), m_pAVIFile( 0 ), m_pAVIStream( 0 ), m_pAVIStreamCompressed( 0 ),
|
||||
m_codec( CodecToFourccCode( codecNoCompression ) )
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if( m_usageCount == 0 )
|
||||
{
|
||||
AVIFileInit();
|
||||
}
|
||||
++m_usageCount;
|
||||
if( pFilename )
|
||||
{
|
||||
HRESULT result = AVIFileOpen( &m_pAVIFile, pFilename, mode, 0 );
|
||||
if( result == AVIERR_OK )
|
||||
{
|
||||
result = AVIFileGetStream( m_pAVIFile, &m_pAVIStream, streamtypeVIDEO, 0 );
|
||||
}
|
||||
if( result != AVIERR_OK )
|
||||
{
|
||||
AVIFileExit();
|
||||
throw AVIWrapperException( AVIErrorToString( result ).c_str() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
AVIWrapper::~AVIWrapper( void )
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if( m_pAVIFile )
|
||||
{
|
||||
CloseStreamsAndFiles();
|
||||
}
|
||||
--m_usageCount;
|
||||
if( m_usageCount == 0 )
|
||||
{
|
||||
AVIFileExit();
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
/*!
|
||||
\brief Closes the AVI file again.
|
||||
|
||||
Closes all open streams and the AVI file itself. At the moment only one stream can be opened
|
||||
at the same time.
|
||||
*/
|
||||
void AVIWrapper::CloseAVIFile( void )
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if( !m_pAVIFile )
|
||||
{
|
||||
throw AVIWrapperException( "CloseAVIFile: No file has been opened so far" );
|
||||
}
|
||||
CloseStreamsAndFiles();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
/*!
|
||||
\brief Closes all open stream and the AVI file itself.
|
||||
*/
|
||||
void AVIWrapper::CloseStreamsAndFiles( void )
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if( m_pAVIStream )
|
||||
{
|
||||
AVIStreamRelease( m_pAVIStream );
|
||||
}
|
||||
if( m_pAVIStreamCompressed )
|
||||
{
|
||||
AVIStreamRelease( m_pAVIStreamCompressed );
|
||||
}
|
||||
if( m_pAVIFile )
|
||||
{
|
||||
AVIFileRelease( m_pAVIFile );
|
||||
}
|
||||
m_pAVIStream = 0;
|
||||
m_pAVIStreamCompressed = 0;
|
||||
m_pAVIFile = 0;
|
||||
m_AVIStreamFrameCounter = 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
/*!
|
||||
\brief Creates an AVI stream from DIB images.
|
||||
\param w The width of the images to be stored in the stream
|
||||
\param h The height of the images to be stored in the stream
|
||||
\param sampleRate The frames per second entry in the AVI header
|
||||
\param quality The JPEG quality (from 0 - 10000)
|
||||
\param name The name of the stream in the file
|
||||
\param codec The codec to be used for the compression of the DIB data. Pass \e codecMax if
|
||||
you want to select a codec from the standard Windows compression dialog or
|
||||
a valid codec from the \b CODEC_T enumeration.
|
||||
|
||||
Use this function to create a compressed or uncompressed AVI stream from images in DIB/Bitmap
|
||||
format. The images can be stored in a compressed format defined by the specified compression
|
||||
handler.
|
||||
|
||||
If your images are already in JPEG format use the function <b>AVIWrapper::CreateAVIStreamFromJPEGs()</b>
|
||||
instead.
|
||||
*/
|
||||
void AVIWrapper::CreateAVIStreamFromDIBs( int w, int h, int bitcount, DWORD sampleRate, DWORD quality, const char* pName /*= "default"*/, CODEC_T codec /*= codecMax*/ )
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
BITMAPINFOHEADER BmpHeader;
|
||||
SetupStreamStructs( BmpHeader, w, h, bitcount, sampleRate, quality, pName, codec );
|
||||
BmpHeader.biCompression = BI_RGB;
|
||||
AVICOMPRESSOPTIONS* opts[1] = {&m_AVICompressionOptions};
|
||||
memset( &m_AVICompressionOptions, 0, sizeof( AVICOMPRESSOPTIONS ) );
|
||||
PAVISTREAM streams[1] = {m_pAVIStream};
|
||||
|
||||
if( codec == codecMax )
|
||||
{
|
||||
// show windows compression handler dialog
|
||||
AVISaveOptions( 0, 0, 1, ( PAVISTREAM* )&streams, ( LPAVICOMPRESSOPTIONS* )&opts );
|
||||
}
|
||||
else // fill AVICOMPRESSOPTIONS with user parameters
|
||||
{
|
||||
m_codec = codec;
|
||||
opts[0]->fccType = streamtypeVIDEO;
|
||||
opts[0]->fccHandler = CodecToFourccCode( codec );
|
||||
opts[0]->dwQuality = quality;
|
||||
opts[0]->dwFlags = AVICOMPRESSF_VALID;
|
||||
}
|
||||
m_codec = opts[0]->fccHandler;
|
||||
HRESULT result = AVIMakeCompressedStream( &m_pAVIStreamCompressed, m_pAVIStream, &m_AVICompressionOptions, NULL );
|
||||
if( result == AVIERR_OK )
|
||||
{
|
||||
result = AVIStreamSetFormat( m_pAVIStreamCompressed, 0, &BmpHeader, sizeof( BITMAPINFOHEADER ) );
|
||||
}
|
||||
if( result != AVIERR_OK )
|
||||
{
|
||||
CloseStreamsAndFiles();
|
||||
throw AVIWrapperException( AVIErrorToString( result ).c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
/*!
|
||||
\brief Creates an AVI stream from JPEG images.
|
||||
\param w The width of the images to be stored in the stream
|
||||
\param h The height of the images to be stored in the stream
|
||||
\param sampleRate The frames per second entry in the AVI header
|
||||
\param quality The JPEG quality (from 0 - 10000)
|
||||
\param name The name of the stream in the file
|
||||
|
||||
Use this function to create a MJPEG stream from images which are already in JPEG format.
|
||||
|
||||
To create an AVI stream from images in DIB format use the function
|
||||
<b>AVIWrapper::CreateAVIStreamFromDIBs()</b> instead.
|
||||
*/
|
||||
void AVIWrapper::CreateAVIStreamFromJPEGs( int w, int h, int bitcount, DWORD sampleRate, DWORD quality, const char* pName /*= "default"*/ )
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// no 'handler' compression! This section works for already compressed images
|
||||
BITMAPINFOHEADER BmpHeader;
|
||||
SetupStreamStructs( BmpHeader, w, h, bitcount, sampleRate, quality, pName, codecMorganMjpg );
|
||||
BmpHeader.biCompression = CodecToFourccCode( codecMorganMjpg );
|
||||
const HRESULT result = AVIStreamSetFormat( m_pAVIStream, 0, &BmpHeader, sizeof( BITMAPINFOHEADER ) );
|
||||
if( result != AVIERR_OK )
|
||||
{
|
||||
CloseStreamsAndFiles();
|
||||
throw AVIWrapperException( AVIErrorToString( result ).c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
/*!
|
||||
\brief Opens an AVI file.
|
||||
\param filename The name of the file to be created/opened/used.
|
||||
\param mode The access mode for this file.
|
||||
|
||||
Opens and creates an AVI file in the mode specified by the \e mode parameter
|
||||
See MSDN for details about the available modes.
|
||||
*/
|
||||
void AVIWrapper::OpenAVIFile( const char* pFilename, UINT mode /* = OF_READ */ )
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if( m_pAVIFile )
|
||||
{
|
||||
throw AVIWrapperException( "OpenAVIFile: Another file has been opened already" );
|
||||
}
|
||||
if( !pFilename )
|
||||
{
|
||||
throw AVIWrapperException( "OpenAVIFile: No valid filename has been specified" );
|
||||
}
|
||||
const HRESULT result = AVIFileOpen( &m_pAVIFile, pFilename, mode, 0 );
|
||||
if( result != AVIERR_OK )
|
||||
{
|
||||
throw AVIWrapperException( AVIErrorToString( result ).c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
/*!
|
||||
\brief Stores one image in the AVI stream
|
||||
\param data Pointer to the image data
|
||||
\param size Size (in bytes) of the memory block pointed to by \e data
|
||||
|
||||
This function stores one image in the specified stream.
|
||||
*/
|
||||
void AVIWrapper::SaveDataToAVIStream( unsigned char* pData, int size )
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
PAVISTREAM pAVIStream = ( m_pAVIStreamCompressed ) ? m_pAVIStreamCompressed : m_pAVIStream;
|
||||
if( !pAVIStream )
|
||||
{
|
||||
throw AVIWrapperException( "SaveDataToAVIStream: Stream pointer invalid" );
|
||||
}
|
||||
const HRESULT result = AVIStreamWrite( pAVIStream, m_AVIStreamFrameCounter++, 1, pData, size, AVIIF_KEYFRAME, 0, 0 );
|
||||
if( result != AVIERR_OK )
|
||||
{
|
||||
throw AVIWrapperException( AVIErrorToString( result ).c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void AVIWrapper::SetupStreamStructs( BITMAPINFOHEADER& BmpHeader, int w, int h, int bitcount, DWORD sampleRate, DWORD quality, const char* pName /*= "default"*/, CODEC_T codec /*= codecMax*/ )
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if( !m_pAVIFile )
|
||||
{
|
||||
throw AVIWrapperException( "CreateNewAVIStream: No file has been opened so far" );
|
||||
}
|
||||
if( strlen( pName ) > sizeof( m_AVIStreamInfo.szName ) )
|
||||
{
|
||||
throw AVIWrapperException( "CreateNewAVIStream: stream name too long" );
|
||||
}
|
||||
if( m_pAVIStream || m_pAVIStreamCompressed )
|
||||
{
|
||||
throw AVIWrapperException( "CreateNewAVIStream: There is already an open stream" );
|
||||
}
|
||||
// setup AVISTREAMINFO structure
|
||||
memset( &m_AVIStreamInfo, 0, sizeof( AVISTREAMINFO ) );
|
||||
m_AVIStreamInfo.fccType = streamtypeVIDEO;
|
||||
m_AVIStreamInfo.fccHandler = CodecToFourccCode( codec );
|
||||
m_AVIStreamInfo.wPriority = 10;
|
||||
m_AVIStreamInfo.dwScale = 1;
|
||||
m_AVIStreamInfo.dwRate = sampleRate;
|
||||
m_AVIStreamInfo.dwQuality = quality;
|
||||
m_AVIStreamInfo.rcFrame.right = w;
|
||||
m_AVIStreamInfo.rcFrame.bottom = h;
|
||||
mv_strncpy_s( m_AVIStreamInfo.szName, pName, sizeof( m_AVIStreamInfo.szName ) );
|
||||
|
||||
const HRESULT result = AVIFileCreateStream( m_pAVIFile, &m_pAVIStream, &m_AVIStreamInfo );
|
||||
if( result != AVIERR_OK )
|
||||
{
|
||||
throw AVIWrapperException( AVIErrorToString( result ).c_str() );
|
||||
}
|
||||
// setup BITMAPINFOHEADER structure
|
||||
memset( &BmpHeader, 0, sizeof( BITMAPINFOHEADER ) );
|
||||
BmpHeader.biSize = sizeof( BITMAPINFOHEADER );
|
||||
BmpHeader.biWidth = w;
|
||||
BmpHeader.biHeight = h;
|
||||
BmpHeader.biPlanes = 1;
|
||||
BmpHeader.biBitCount = static_cast<WORD>( bitcount );
|
||||
|
||||
// setup internals
|
||||
m_AVIStreamFrameCounter = 0;
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
//----------------------------------------------------------------------------------------
|
||||
#ifndef aviwrapperH
|
||||
#define aviwrapperH aviwrapperH
|
||||
//----------------------------------------------------------------------------------------
|
||||
#include "avihelper.h"
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
class AVIWrapper
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// member data
|
||||
/// Keeps track about the number of images stored in the actual stream
|
||||
int m_AVIStreamFrameCounter;
|
||||
/// pointer to the structure describing the AVI-file
|
||||
PAVIFILE m_pAVIFile;
|
||||
/// pointer to an uncompressed AVI stream
|
||||
PAVISTREAM m_pAVIStream;
|
||||
/// pointer to a compressed AVI stream (this is used when a compression handler is used)
|
||||
PAVISTREAM m_pAVIStreamCompressed;
|
||||
/// A structure containing information about the AVI stream
|
||||
AVISTREAMINFO m_AVIStreamInfo;
|
||||
/// A structure for storing the compression options of the AVI stream
|
||||
AVICOMPRESSOPTIONS m_AVICompressionOptions;
|
||||
/// The used codec
|
||||
DWORD m_codec;
|
||||
/// Usage count for this class
|
||||
static unsigned int m_usageCount;
|
||||
// functions
|
||||
void CloseStreamsAndFiles( void );
|
||||
void SetupStreamStructs( BITMAPINFOHEADER& BmpHeader, int w, int h, int bitcount, DWORD sampleRate, DWORD quality, const char* pName = "default", CODEC_T codec = codecMax );
|
||||
/// Do not allow copy construction
|
||||
AVIWrapper( const AVIWrapper& scr );
|
||||
public:
|
||||
// construction/destruction
|
||||
explicit AVIWrapper( const char* pFilename = 0, UINT mode = OF_READ );
|
||||
~AVIWrapper( void );
|
||||
|
||||
// user interface
|
||||
void CloseAVIFile( void );
|
||||
void CreateAVIStreamFromDIBs( int w, int h, int bitcount, DWORD sampleRate, DWORD quality, const char* pName = "default", CODEC_T codec = codecMax );
|
||||
void CreateAVIStreamFromJPEGs( int w, int h, int bitcount, DWORD sampleRate, DWORD quality, const char* pName = "default" );
|
||||
const char* GetStreamName( void ) const
|
||||
{
|
||||
return m_AVIStreamInfo.szName;
|
||||
}
|
||||
bool UsesCompressionHandler( void ) const
|
||||
{
|
||||
return m_codec != CodecToFourccCode( codecNoCompression );
|
||||
}
|
||||
void OpenAVIFile( const char* pFilename, UINT mode = OF_READ );
|
||||
void SaveDataToAVIStream( unsigned char* pData, int size );
|
||||
};
|
||||
|
||||
#endif // aviwrapperH
|
@ -0,0 +1,545 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef exampleHelperH
|
||||
#define exampleHelperH exampleHelperH
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <mvIMPACT_CPP/mvIMPACT_acquire.h>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template<class _Ty>
|
||||
class DisplayDictEntry
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
public:
|
||||
void operator()( const std::pair<std::string, _Ty>& data ) const
|
||||
{
|
||||
std::cout << " [" << data.second << "]: " << data.first << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class DisplayComponent
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
public:
|
||||
void operator()( const Component& data ) const
|
||||
{
|
||||
if( data.isValid() )
|
||||
{
|
||||
std::cout << " " << data.name() << "(" << data.typeAsString() << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class DisplayProperty
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
public:
|
||||
void operator()( const std::pair<std::string, mvIMPACT::acquire::Property>& data ) const
|
||||
{
|
||||
if( data.second.isValid() )
|
||||
{
|
||||
std::cout << data.first << ": " << data.second.readSArray() << "(" << data.second.flagsAsString() << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template<class _Ty>
|
||||
void DisplayPropertyDictionary( const mvIMPACT::acquire::Property& p )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
_Ty prop( p );
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1300) // is 'old' VC 6 Microsoft compiler?
|
||||
std::vector<std::pair<std::string, _Ty::value_type> > dict;
|
||||
prop.getTranslationDict( dict );
|
||||
std::for_each( dict.begin(), dict.end(), DisplayDictEntry<_Ty::value_type>() );
|
||||
#else
|
||||
std::vector<std::pair<std::string, typename _Ty::value_type> > dict;
|
||||
prop.getTranslationDict( dict );
|
||||
std::for_each( dict.begin(), dict.end(), DisplayDictEntry<typename _Ty::value_type>() );
|
||||
#endif // #ifdef _MSC_VER
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \brief Checks is a certain value for property is supported.
|
||||
template<class _Tx>
|
||||
bool supportsEnumStringValue( const _Tx& prop, const std::string& value )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( prop.hasDict() )
|
||||
{
|
||||
typename std::vector<std::string> sequence;
|
||||
prop.getTranslationDictStrings( sequence );
|
||||
return std::find( sequence.begin(), sequence.end(), value ) != sequence.end();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \brief Checks is a certain value for property is supported.
|
||||
template<class _Tx, typename _Ty>
|
||||
bool supportsValue( const _Tx& prop, const _Ty& value )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( prop.hasDict() )
|
||||
{
|
||||
typename std::vector<_Ty> sequence;
|
||||
prop.getTranslationDictValues( sequence );
|
||||
return std::find( sequence.begin(), sequence.end(), value ) != sequence.end();
|
||||
}
|
||||
|
||||
if( prop.hasMinValue() && ( prop.getMinValue() > value ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if( prop.hasMaxValue() && ( prop.getMaxValue() < value ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \brief Sets a property to a certain value if this value is supported.
|
||||
template<typename _Ty, typename _Tx>
|
||||
void conditionalSetProperty( const _Ty& prop, const _Tx& value, bool boSilent = false )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( prop.isValid() && prop.isWriteable() && supportsValue( prop, value ) )
|
||||
{
|
||||
prop.write( value );
|
||||
if( !boSilent )
|
||||
{
|
||||
std::cout << "Property '" << prop.name() << "' set to '" << prop.readS() << "'." << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \brief Sets a property to a certain value if this value is supported.
|
||||
template<typename _Ty>
|
||||
void conditionalSetEnumPropertyByString( const _Ty& prop, const std::string& value, bool boSilent = false )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( prop.isValid() && prop.isWriteable() && supportsEnumStringValue( prop, value ) )
|
||||
{
|
||||
prop.writeS( value );
|
||||
if( !boSilent )
|
||||
{
|
||||
std::cout << "Property '" << prop.name() << "' set to '" << prop.readS() << "'." << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// This function makes heavy use of strings. In real world applications
|
||||
/// this can be avoided if optimal performance is crucial. All properties can be modified
|
||||
/// via strings, but most properties can also be modified with numerical (int / double )
|
||||
/// values, which is much faster, but not as descriptive for a sample application
|
||||
inline void displayPropertyData( const mvIMPACT::acquire::Property& prop )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
const std::string name( prop.name() );
|
||||
std::cout << std::endl
|
||||
<< "Property '" << name << "'(display name: '" << prop.displayName() << "', type: " << prop.typeAsString() << ") currently specifies the following flags: " << prop.flagsAsString() << std::endl
|
||||
<< std::endl;
|
||||
const std::string doc( prop.docString() );
|
||||
if( !doc.empty() )
|
||||
{
|
||||
std::cout << "The following documentation has been reported by the driver for this feature: " << std::endl
|
||||
<< doc << std::endl
|
||||
<< std::endl;
|
||||
}
|
||||
if( prop.selectedFeatureCount() > 0 )
|
||||
{
|
||||
std::vector<Component> selectedFeatureList;
|
||||
prop.selectedFeatures( selectedFeatureList );
|
||||
std::cout << "The following features are selected by this feature(Whenever the current feature is modified, all selected features might change):" << std::endl;
|
||||
std::for_each( selectedFeatureList.begin(), selectedFeatureList.end(), DisplayComponent() );
|
||||
std::cout << std::endl;
|
||||
}
|
||||
if( prop.selectingFeatureCount() > 0 )
|
||||
{
|
||||
std::vector<Component> selectingFeatureList;
|
||||
prop.selectingFeatures( selectingFeatureList );
|
||||
std::cout << "The following features select this feature(Whenever a selecting features is modified, a selected one might change):" << std::endl;
|
||||
std::for_each( selectingFeatureList.begin(), selectingFeatureList.end(), DisplayComponent() );
|
||||
std::cout << std::endl;
|
||||
}
|
||||
if( prop.hasMinValue() )
|
||||
{
|
||||
std::cout << "The minimum value of '" << name << "' is " << prop.readS( mvIMPACT::acquire::plMinValue ) << std::endl;
|
||||
}
|
||||
if( prop.hasMaxValue() )
|
||||
{
|
||||
std::cout << "The maximum value of '" << name << "' is " << prop.readS( mvIMPACT::acquire::plMaxValue ) << std::endl;
|
||||
}
|
||||
if( prop.hasStepWidth() )
|
||||
{
|
||||
std::cout << "The increment of '" << name << "' is " << prop.readS( mvIMPACT::acquire::plStepWidth ) << std::endl;
|
||||
}
|
||||
if( prop.hasDict() )
|
||||
{
|
||||
std::cout << "'" << name << "' defines a dictionary. Valid values are: " << std::endl;
|
||||
mvIMPACT::acquire::TComponentType type = prop.type();
|
||||
if( type == mvIMPACT::acquire::ctPropInt )
|
||||
{
|
||||
DisplayPropertyDictionary<mvIMPACT::acquire::PropertyI>( prop );
|
||||
}
|
||||
else if( type == mvIMPACT::acquire::ctPropInt64 )
|
||||
{
|
||||
DisplayPropertyDictionary<mvIMPACT::acquire::PropertyI64>( prop );
|
||||
}
|
||||
else if( type == mvIMPACT::acquire::ctPropFloat )
|
||||
{
|
||||
DisplayPropertyDictionary<mvIMPACT::acquire::PropertyF>( prop );
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Error! Unhandled enum prop type: " << prop.typeAsString() << std::endl;
|
||||
}
|
||||
}
|
||||
std::cout << "The current value of '" << name << "' is: '" << prop.readS() << "'" << std::endl;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool displayPropertyDataWithValidation( const mvIMPACT::acquire::Property& prop, const std::string& name )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( !prop.isValid() )
|
||||
{
|
||||
std::cout << "Property '" << name << "' is not supported/available." << std::endl;
|
||||
return false;
|
||||
}
|
||||
displayPropertyData( prop );
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Start the acquisition manually if this was requested(this is to prepare the driver for data capture and tell the device to start streaming data)
|
||||
inline void manuallyStartAcquisitionIfNeeded( mvIMPACT::acquire::Device* pDev, const mvIMPACT::acquire::FunctionInterface& fi )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( pDev->acquisitionStartStopBehaviour.read() == mvIMPACT::acquire::assbUser )
|
||||
{
|
||||
const mvIMPACT::acquire::TDMR_ERROR result = static_cast<mvIMPACT::acquire::TDMR_ERROR>( fi.acquisitionStart() );
|
||||
if( result != mvIMPACT::acquire::DMR_NO_ERROR )
|
||||
{
|
||||
std::cout << "'FunctionInterface.acquisitionStart' returned with an unexpected result: " << result
|
||||
<< "(" << mvIMPACT::acquire::ImpactAcquireException::getErrorCodeAsString( result ) << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Stop the acquisition manually if this was requested
|
||||
inline void manuallyStopAcquisitionIfNeeded( mvIMPACT::acquire::Device* pDev, const mvIMPACT::acquire::FunctionInterface& fi )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( pDev->acquisitionStartStopBehaviour.read() == mvIMPACT::acquire::assbUser )
|
||||
{
|
||||
const mvIMPACT::acquire::TDMR_ERROR result = static_cast<mvIMPACT::acquire::TDMR_ERROR>( fi.acquisitionStop() );
|
||||
if( result != mvIMPACT::acquire::DMR_NO_ERROR )
|
||||
{
|
||||
std::cout << "'FunctionInterface.acquisitionStop' returned with an unexpected result: " << result
|
||||
<< "(" << mvIMPACT::acquire::ImpactAcquireException::getErrorCodeAsString( result ) << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// This function makes heavy use of strings. In real world applications
|
||||
/// this can be avoided if optimal performance is crucial. All properties can be modified
|
||||
/// via strings, but most properties can also be modified with numerical (int / double )
|
||||
/// values, which is much faster, but not as descriptive for a sample application
|
||||
inline void modifyPropertyValue( const mvIMPACT::acquire::Property& prop, const std::string& param = "", const std::string& index = "" )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
try
|
||||
{
|
||||
const std::string name( prop.name() );
|
||||
if( prop.isWriteable() )
|
||||
{
|
||||
int valIndex = 0;
|
||||
if( param.empty() )
|
||||
{
|
||||
std::cout << "Enter the new value for '" << name << "': ";
|
||||
std::string val;
|
||||
std::cin >> val;
|
||||
// remove the '\n' from the stream
|
||||
std::cin.get();
|
||||
if( prop.valCount() > 1 )
|
||||
{
|
||||
std::cout << "'" << name << "' defines " << prop.valCount() << " values. Enter the index (zero-based) of the value to modify: ";
|
||||
std::cin >> valIndex;
|
||||
// remove the '\n' from the stream
|
||||
std::cin.get();
|
||||
}
|
||||
prop.writeS( val, valIndex );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !index.empty() )
|
||||
{
|
||||
valIndex = atoi( index.c_str() );
|
||||
}
|
||||
prop.writeS( param, valIndex );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "'" << name << "' is read-only, thus can't be modified." << std::endl;
|
||||
}
|
||||
}
|
||||
catch( const mvIMPACT::acquire::ImpactAcquireException& e )
|
||||
{
|
||||
std::cout << "An exception occurred: " << e.getErrorString() << "(error code: " << e.getErrorCodeAsString() << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline void displayAndModifyPropertyDataWithValidation( const mvIMPACT::acquire::Property& prop, const std::string& name )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( displayPropertyDataWithValidation( prop, name ) )
|
||||
{
|
||||
modifyPropertyValue( prop );
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline std::ostream& operator<<( std::ostream& out, const mvIMPACT::acquire::Property& prop )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
out << prop.name() << ": " << prop.readS();
|
||||
return out;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \brief Allows string comparison with a defined character to ignore
|
||||
/**
|
||||
* This function allows a tolerant string compare. If \a candidate ends with \a wildcard
|
||||
* \a candidate can be shorter then \a searchString as the rest of the string will be
|
||||
* ignored. This is a helper function used internally by <b>DeviceManager</b> objects.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* \code
|
||||
* wildcard = '*'
|
||||
* s1 = "blablabla"
|
||||
* match( s1, "bl*bl*bla", '*' ); // will return 0
|
||||
* // will return 0 ('*' is the default value for parameter 3 )
|
||||
* match( s1, "bl*" );
|
||||
* // the next call will return -1 as the first character MUST
|
||||
* // be either a 'b' or the wildcard character.
|
||||
* match( s1, "a*" );
|
||||
* \endcode
|
||||
* \return
|
||||
* - 0 if successful
|
||||
* - -1 otherwise
|
||||
*/
|
||||
template<class _Elem, class _Traits, class _Ax>
|
||||
int match( const std::basic_string<_Elem, _Traits, _Ax>& searchString, const std::basic_string<_Elem, _Traits, _Ax>& candidate, _Elem wildcard )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
typename std::basic_string<_Elem, _Traits, _Ax>::size_type searchLength = searchString.length();
|
||||
// determine search length
|
||||
if( candidate.length() < searchString.length() )
|
||||
{
|
||||
if( candidate.empty() )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( candidate[candidate.length() - 1] != wildcard )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
searchLength = candidate.length() - 1;
|
||||
}
|
||||
// search
|
||||
for( typename std::basic_string<_Elem, _Traits, _Ax>::size_type i = 0; i < searchLength; i++ )
|
||||
{
|
||||
if( ( candidate[i] != searchString[i] ) && ( candidate[i] != wildcard ) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef bool( *SUPPORTED_DEVICE_CHECK )( const mvIMPACT::acquire::Device* const );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline mvIMPACT::acquire::Device* getDeviceFromUserInput( const mvIMPACT::acquire::DeviceManager& devMgr, SUPPORTED_DEVICE_CHECK pSupportedDeviceCheckFn = 0, bool boSilent = false, bool boAutomaticallyUseGenICamInterface = true )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
const unsigned int devCnt = devMgr.deviceCount();
|
||||
if( devCnt == 0 )
|
||||
{
|
||||
std::cout << "No compliant device found!" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::set<unsigned int> validDeviceNumbers;
|
||||
|
||||
// display every device detected that matches
|
||||
for( unsigned int i = 0; i < devCnt; i++ )
|
||||
{
|
||||
Device* pDev = devMgr[i];
|
||||
if( pDev )
|
||||
{
|
||||
if( !pSupportedDeviceCheckFn || pSupportedDeviceCheckFn( pDev ) )
|
||||
{
|
||||
std::cout << "[" << i << "]: " << pDev->serial.read() << " (" << pDev->product.read() << ", " << pDev->family.read();
|
||||
if( pDev->interfaceLayout.isValid() )
|
||||
{
|
||||
if( boAutomaticallyUseGenICamInterface )
|
||||
{
|
||||
// if this device offers the 'GenICam' interface switch it on, as this will
|
||||
// allow are better control over GenICam compliant devices
|
||||
conditionalSetProperty( pDev->interfaceLayout, dilGenICam, true );
|
||||
}
|
||||
std::cout << ", interface layout: " << pDev->interfaceLayout.readS();
|
||||
}
|
||||
if( pDev->acquisitionStartStopBehaviour.isValid() )
|
||||
{
|
||||
// if this device offers a user defined acquisition start/stop behaviour
|
||||
// enable it as this allows finer control about the streaming behaviour
|
||||
conditionalSetProperty( pDev->acquisitionStartStopBehaviour, assbUser, true );
|
||||
std::cout << ", acquisition start/stop behaviour: " << pDev->acquisitionStartStopBehaviour.readS();
|
||||
}
|
||||
if( pDev->interfaceLayout.isValid() && !pDev->interfaceLayout.isWriteable() )
|
||||
{
|
||||
if( pDev->isInUse() )
|
||||
{
|
||||
std::cout << ", !!!ALREADY IN USE!!!";
|
||||
}
|
||||
}
|
||||
std::cout << ")" << std::endl;
|
||||
validDeviceNumbers.insert( i );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( validDeviceNumbers.empty() )
|
||||
{
|
||||
std::cout << devMgr.deviceCount() << " devices have been detected:" << std::endl;
|
||||
for( unsigned int i = 0; i < devCnt; i++ )
|
||||
{
|
||||
Device* pDev = devMgr[i];
|
||||
if( pDev )
|
||||
{
|
||||
std::cout << " [" << i << "]: " << pDev->serial.read() << " (" << pDev->product.read() << ", " << pDev->family.read() << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
std::cout << "However none of these devices seems to be supported by this sample." << std::endl << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// get user input
|
||||
std::cout << std::endl << "Please enter the number in front of the listed device followed by [ENTER] to open it: ";
|
||||
unsigned int devNr = 0;
|
||||
std::cin >> devNr;
|
||||
// remove the '\n' from the stream
|
||||
std::cin.get();
|
||||
|
||||
if( validDeviceNumbers.find( devNr ) == validDeviceNumbers.end() )
|
||||
{
|
||||
std::cout << "Invalid selection!" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( !boSilent )
|
||||
{
|
||||
std::cout << "Using device number " << devNr << "." << std::endl;
|
||||
}
|
||||
return devMgr[devNr];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline std::vector<mvIMPACT::acquire::Device*>::size_type getValidDevices( const mvIMPACT::acquire::DeviceManager& devMgr, std::vector<mvIMPACT::acquire::Device*>& v, SUPPORTED_DEVICE_CHECK pSupportedDeviceCheckFn = 0 )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
const unsigned int devCnt = devMgr.deviceCount();
|
||||
// display every device detected that matches
|
||||
for( unsigned int i = 0; i < devCnt; i++ )
|
||||
{
|
||||
Device* pDev = devMgr[i];
|
||||
if( pDev )
|
||||
{
|
||||
if( !pSupportedDeviceCheckFn || pSupportedDeviceCheckFn( pDev ) )
|
||||
{
|
||||
v.push_back( pDev );
|
||||
}
|
||||
}
|
||||
}
|
||||
return v.size();
|
||||
}
|
||||
|
||||
#if defined(linux) || defined(__linux) || defined(__linux__)
|
||||
# include <fcntl.h>
|
||||
# include <stdio.h>
|
||||
# include <sys/types.h>
|
||||
# include <termios.h>
|
||||
# include <unistd.h>
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \brief Checks if something was written to a certain file descriptor
|
||||
/** \return
|
||||
* - 0 if timeout did elapse
|
||||
* - 1 otherwise
|
||||
*/
|
||||
inline unsigned waitForInput( int maxWait_sec, int fd )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
fd_set rfds;
|
||||
struct timeval tv;
|
||||
|
||||
FD_ZERO( &rfds );
|
||||
#ifndef __clang_analyzer__ // See https://bugs.llvm.org/show_bug.cgi?id=8920
|
||||
FD_SET( fd, &rfds );
|
||||
#endif // #ifndef __clang_analyzer__
|
||||
|
||||
tv.tv_sec = maxWait_sec;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
return select( fd + 1, &rfds, NULL, NULL, &tv );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** \return
|
||||
* - 1 if a key has been pressed since the last call to this function
|
||||
* - 0 otherwise
|
||||
*/
|
||||
inline int checkKeyboardInput( void )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
struct termios oldt, newt;
|
||||
tcgetattr( STDIN_FILENO, &oldt );
|
||||
newt = oldt;
|
||||
newt.c_lflag &= ~( ICANON | ECHO );
|
||||
tcsetattr( STDIN_FILENO, TCSANOW, &newt );
|
||||
const int oldf = fcntl( STDIN_FILENO, F_GETFL, 0 );
|
||||
fcntl( STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK );
|
||||
const int ch = getchar();
|
||||
tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
|
||||
fcntl( STDIN_FILENO, F_SETFL, oldf );
|
||||
if( ch != EOF )
|
||||
{
|
||||
// ungetc(ch, stdin);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif // #if defined(linux) || defined(__linux) || defined(__linux__)
|
||||
|
||||
#endif // exampleHelperH
|
@ -0,0 +1,599 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "exampleHelper_C.h"
|
||||
|
||||
#define BUF_SIZE (32)
|
||||
#define BUF_SIZE_LARGE (256)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
int getIntValFromSTDIn( void )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
int value;
|
||||
int conversionResult = 0;
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400) // is at least VC 2005 compiler?
|
||||
conversionResult = scanf_s( "%d", &value );
|
||||
#else
|
||||
conversionResult = scanf( "%d", &value );
|
||||
#endif // #if defined(_MSC_VER) && (_MSC_VER >= 1400) // is at least VC 2005 compiler?
|
||||
if( conversionResult != 1 )
|
||||
{
|
||||
printf( "Conversion error: Expected: 1, conversion result: %d.\n", conversionResult );
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
int getPropI( HOBJ hProp, int index )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
int value = 0;
|
||||
TPROPHANDLING_ERROR result = PROPHANDLING_NO_ERROR;
|
||||
|
||||
if( ( result = OBJ_GetI( hProp, &value, index ) ) != PROPHANDLING_NO_ERROR )
|
||||
{
|
||||
printf( "getPropI: Failed to read property value(%s).\n", DMR_ErrorCodeToString( result ) );
|
||||
exit( 42 );
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void setPropI( HOBJ hProp, int value, int index )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
TPROPHANDLING_ERROR result = PROPHANDLING_NO_ERROR;
|
||||
|
||||
if( ( result = OBJ_SetI( hProp, value, index ) ) != PROPHANDLING_NO_ERROR )
|
||||
{
|
||||
printf( "setPropI: Failed to write property value(%s).\n", DMR_ErrorCodeToString( result ) );
|
||||
exit( 42 );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
int64_type getPropI64( HOBJ hProp, int index )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
int64_type value = 0;
|
||||
TPROPHANDLING_ERROR result = PROPHANDLING_NO_ERROR;
|
||||
|
||||
if( ( result = OBJ_GetI64( hProp, &value, index ) ) != PROPHANDLING_NO_ERROR )
|
||||
{
|
||||
printf( "getPropI: Failed to read property value(%s).\n", DMR_ErrorCodeToString( result ) );
|
||||
exit( 42 );
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void setPropI64( HOBJ hProp, int64_type value, int index )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
TPROPHANDLING_ERROR result = PROPHANDLING_NO_ERROR;
|
||||
|
||||
if( ( result = OBJ_SetI64( hProp, value, index ) ) != PROPHANDLING_NO_ERROR )
|
||||
{
|
||||
printf( "setPropI: Failed to write property value(%s).\n", DMR_ErrorCodeToString( result ) );
|
||||
exit( 42 );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void* getPropP( HOBJ hProp, int index )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
void* value = 0;
|
||||
TPROPHANDLING_ERROR result = PROPHANDLING_NO_ERROR;
|
||||
|
||||
if( ( result = OBJ_GetP( hProp, &value, index ) ) != PROPHANDLING_NO_ERROR )
|
||||
{
|
||||
printf( "getPropP: Failed to read property value(%s).\n", DMR_ErrorCodeToString( result ) );
|
||||
exit( 42 );
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void setPropP( HOBJ hProp, void* value, int index )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
TPROPHANDLING_ERROR result = PROPHANDLING_NO_ERROR;
|
||||
|
||||
if( ( result = OBJ_SetP( hProp, value, index ) ) != PROPHANDLING_NO_ERROR )
|
||||
{
|
||||
printf( "setPropP: Failed to write property value(%s).\n", DMR_ErrorCodeToString( result ) );
|
||||
exit( 42 );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void setPropS( HOBJ hProp, const char* pVal, int index )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
TPROPHANDLING_ERROR result = PROPHANDLING_NO_ERROR;
|
||||
|
||||
if( ( result = OBJ_SetS( hProp, pVal, index ) ) != PROPHANDLING_NO_ERROR )
|
||||
{
|
||||
printf( "setPropS: Failed to write property value %s :%s.\n", pVal, DMR_ErrorCodeToString( result ) );
|
||||
exit( 42 );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This function will try to obtain the handle to a certain driver feature
|
||||
HOBJ getDriverFeature( HDRV hDrv, const char* pFeatureName, const char* pFeatureType, const char* pAddListName, TDMR_ListType type, unsigned int searchMode )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
TDMR_ERROR dmrResult = DMR_NO_ERROR;
|
||||
HOBJ hObj = INVALID_ID;
|
||||
HLIST baseList = INVALID_ID;
|
||||
|
||||
// try to locate the base list for these property
|
||||
if( ( dmrResult = DMR_FindList( hDrv, pAddListName, type, 0, &baseList ) ) == DMR_NO_ERROR )
|
||||
{
|
||||
// try to locate the property
|
||||
TPROPHANDLING_ERROR objResult;
|
||||
if( ( objResult = OBJ_GetHandleEx( baseList, pFeatureName, &hObj, searchMode, INT_MAX ) ) != PROPHANDLING_NO_ERROR )
|
||||
{
|
||||
printf( "OBJ_GetHandleEx for '%s' failed: %d Handle: %d. This %s might not be supported by this device\n", pFeatureName, objResult, hObj, pFeatureType );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "DMR_FindList failed: %d. Lists of type %d are not available for this device\n", dmrResult, type );
|
||||
}
|
||||
return hObj;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This function will try to obtain the handle to a certain driver feature list
|
||||
HOBJ getDriverList( HDRV hDrv, const char* pListName, const char* pAddListName, TDMR_ListType type )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return getDriverFeature( hDrv, pListName, "list", pAddListName, type, smIgnoreProperties | smIgnoreMethods );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This function will try to obtain the handle to a certain driver property
|
||||
HOBJ getDriverProperty( HDRV hDrv, const char* pPropName, const char* pAddListName, TDMR_ListType type )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return getDriverFeature( hDrv, pPropName, "property", pAddListName, type, smIgnoreLists | smIgnoreMethods );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This function will try to obtain the handle to a certain driver property
|
||||
HOBJ getDriverMethod( HDRV hDrv, const char* pPropName, const char* pAddListName, TDMR_ListType type )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return getDriverFeature( hDrv, pPropName, "method", pAddListName, type, smIgnoreProperties | smIgnoreLists );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
HOBJ getDeviceProp( HDEV hDev, const char* pPropName )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
TPROPHANDLING_ERROR objResult;
|
||||
HOBJ hProp = INVALID_ID;
|
||||
|
||||
// try to locate the property
|
||||
if( ( objResult = OBJ_GetHandleEx( hDev, pPropName, &hProp, 0, -1 ) ) != PROPHANDLING_NO_ERROR )
|
||||
{
|
||||
printf( "OBJ_GetHandleEx failed for property '%s': %d Handle: %d\n", pPropName, objResult, hProp );
|
||||
}
|
||||
return hProp;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
HOBJ getInfoProp( HDRV hDrv, const char* pPropName )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return getDriverProperty( hDrv, pPropName, 0, dmltInfo );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
HOBJ getIOSubSystemProp( HDRV hDrv, const char* pPropName )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return getDriverProperty( hDrv, pPropName, 0, dmltIOSubSystem );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
HOBJ getRequestCtrlProp( HDRV hDrv, const char* pRequestCtrlName, const char* pPropName )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return getDriverProperty( hDrv, pPropName, pRequestCtrlName, dmltRequestCtrl );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
HOBJ getRequestProp( HDRV hDrv, int requestNr, const char* pPropName )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
char buf[BUF_SIZE];
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400) // is at least VC 2005 compiler?
|
||||
sprintf_s( buf, BUF_SIZE, "Entry %d", requestNr );
|
||||
#else
|
||||
sprintf( buf, "Entry %d", requestNr );
|
||||
#endif // #if defined(_MSC_VER) && (_MSC_VER >= 1400) // is at least VC 2005 compiler?
|
||||
return getDriverProperty( hDrv, pPropName, buf, dmltRequest );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
HOBJ getSettingProp( HDRV hDrv, const char* pSettingName, const char* pPropName )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return getDriverProperty( hDrv, pPropName, pSettingName, dmltSetting );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
HOBJ getSettingMethod( HDRV hDrv, const char* pSettingName, const char* pMethodName )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return getDriverMethod( hDrv, pMethodName, pSettingName, dmltSetting );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
HOBJ getStatisticProp( HDRV hDrv, const char* pPropName )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return getDriverProperty( hDrv, pPropName, 0, dmltStatistics );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
HOBJ getSystemSettingProp( HDRV hDrv, const char* pPropName )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return getDriverProperty( hDrv, pPropName, 0, dmltSystemSettings );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
TPROPHANDLING_ERROR getStringValue( HOBJ hObj, char** pBuf, int index )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
size_t bufSize = DEFAULT_STRING_SIZE_LIMIT;
|
||||
TPROPHANDLING_ERROR result = PROPHANDLING_NO_ERROR;
|
||||
static const int BUFFER_INCREMENT_FACTOR = 2;
|
||||
|
||||
*pBuf = ( char* )calloc( 1, bufSize );
|
||||
while( ( result = OBJ_GetS( hObj, *pBuf, bufSize, index ) ) == PROPHANDLING_INPUT_BUFFER_TOO_SMALL )
|
||||
{
|
||||
bufSize *= BUFFER_INCREMENT_FACTOR;
|
||||
*pBuf = ( char* )realloc( *pBuf, bufSize );
|
||||
}
|
||||
if( result != PROPHANDLING_NO_ERROR )
|
||||
{
|
||||
printf( "Error while reading string property value: Error code: %d(%s).\n", result, DMR_ErrorCodeToString( result ) );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
TPROPHANDLING_ERROR getValueAsString( HOBJ hObj, const char* pFormat, char** pBuf, int index )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
size_t bufSize = DEFAULT_STRING_SIZE_LIMIT;
|
||||
TPROPHANDLING_ERROR result = PROPHANDLING_NO_ERROR;
|
||||
|
||||
*pBuf = ( char* )calloc( 1, bufSize );
|
||||
while( ( result = OBJ_GetSFormattedEx( hObj, *pBuf, &bufSize, pFormat, index ) ) == PROPHANDLING_INPUT_BUFFER_TOO_SMALL )
|
||||
{
|
||||
*pBuf = ( char* )realloc( *pBuf, bufSize );
|
||||
}
|
||||
|
||||
if( result != PROPHANDLING_NO_ERROR )
|
||||
{
|
||||
printf( "Error while reading string property value: Error code: %d(%s).\n", result, DMR_ErrorCodeToString( result ) );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Start the acquisition manually if this was requested(this is to prepare the driver for data capture and tell the device to start streaming data)
|
||||
// Whether this is needed or not depends on the property 'AcquisitionStartStopBehaviour' in the list referenced by 'HDEV'.
|
||||
void manuallyStartAcquisitionIfNeeded( HDRV hDrv )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
const TDMR_ERROR result = DMR_AcquisitionStart( hDrv );
|
||||
if( ( result != DMR_NO_ERROR ) &&
|
||||
( result != DMR_FEATURE_NOT_AVAILABLE ) )
|
||||
{
|
||||
printf( "DMR_AcquisitionStart: Unexpected error(code: %d(%s))\n", result, DMR_ErrorCodeToString( result ) );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Stop the acquisition manually if this was requested.
|
||||
// Whether this is needed or not depends on the property 'AcquisitionStartStopBehaviour' in the list referenced by 'HDEV'.
|
||||
void manuallyStopAcquisitionIfNeeded( HDRV hDrv )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
const TDMR_ERROR result = DMR_AcquisitionStop( hDrv );
|
||||
if( ( result != DMR_NO_ERROR ) &&
|
||||
( result != DMR_FEATURE_NOT_AVAILABLE ) )
|
||||
{
|
||||
printf( "DMR_AcquisitionStop: Unexpected error(code: %d(%s))\n", result, DMR_ErrorCodeToString( result ) );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void modifyEnumPropertyI( HDRV hDrv, const char* pSettingName, const char* pPropName )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
HOBJ hProp = INVALID_ID;
|
||||
unsigned int dictValCount = 0;
|
||||
int* dictVals = NULL;
|
||||
TPROPHANDLING_ERROR result = PROPHANDLING_NO_ERROR;
|
||||
|
||||
printf( "Trying to modify property %s:\n", pPropName );
|
||||
if( ( hProp = getSettingProp( hDrv, pSettingName, pPropName ) ) != INVALID_ID )
|
||||
{
|
||||
if( ( result = readTranslationDictValuesI( hProp, &dictVals, &dictValCount, 0 ) ) == PROPHANDLING_NO_ERROR )
|
||||
{
|
||||
int value = 0;
|
||||
printf( "Please select one of the values listed above: " );
|
||||
value = getIntValFromSTDIn();
|
||||
free( dictVals );
|
||||
// set the new trigger mode
|
||||
if( ( result = OBJ_SetI( hProp, value, 0 ) ) != PROPHANDLING_NO_ERROR )
|
||||
{
|
||||
printf( "Failed to set new value for %s. Error code: %d(%s).\n", pPropName, result, DMR_ErrorCodeToString( result ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "Failed to read translation dictionary of property %s. Error code: %d(%s).\n", pPropName, result, DMR_ErrorCodeToString( result ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
TPROPHANDLING_ERROR readTranslationDictValuesI( HOBJ hObj, int** pDictValues, unsigned int* pDictValCnt, unsigned int silent )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
TPROPHANDLING_ERROR funcResult = PROPHANDLING_NO_ERROR;
|
||||
char** ppBuf = 0;
|
||||
unsigned int i = 0;
|
||||
size_t bufSize = 0;
|
||||
const size_t BUFFER_INCREMENT_FACTOR = 6;
|
||||
|
||||
if( ( funcResult = OBJ_GetDictSize( hObj, pDictValCnt ) ) != PROPHANDLING_NO_ERROR )
|
||||
{
|
||||
return funcResult;
|
||||
}
|
||||
|
||||
*pDictValues = ( int* )calloc( *pDictValCnt, sizeof( int ) );
|
||||
if( !( *pDictValues ) )
|
||||
{
|
||||
printf( "Failed to allocate memory for integer dictionary!\n" );
|
||||
return PROPHANDLING_INPUT_BUFFER_TOO_SMALL;
|
||||
}
|
||||
ppBuf = ( char** )calloc( *pDictValCnt, sizeof( char* ) );
|
||||
if( !ppBuf )
|
||||
{
|
||||
free( *pDictValues );
|
||||
printf( "Failed to allocate memory for string dictionary!\n" );
|
||||
return PROPHANDLING_INPUT_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
bufSize = DEFAULT_STRING_SIZE_LIMIT;
|
||||
for( i = 0; i < *pDictValCnt; i++ )
|
||||
{
|
||||
ppBuf[i] = ( char* )calloc( 1, bufSize );
|
||||
}
|
||||
|
||||
while( ( funcResult = OBJ_GetIDictEntries( hObj, ppBuf, bufSize, *pDictValues, ( size_t ) * pDictValCnt ) ) == PROPHANDLING_INPUT_BUFFER_TOO_SMALL )
|
||||
{
|
||||
bufSize *= BUFFER_INCREMENT_FACTOR;
|
||||
for( i = 0; i < *pDictValCnt; i++ )
|
||||
{
|
||||
ppBuf[i] = ( char* )realloc( ppBuf[i], bufSize );
|
||||
}
|
||||
}
|
||||
|
||||
if( ( funcResult == PROPHANDLING_NO_ERROR ) &&
|
||||
( silent == 0 ) )
|
||||
{
|
||||
printf( "Got the following dictionary:\n" );
|
||||
for( i = 0; i < *pDictValCnt; i++ )
|
||||
{
|
||||
printf( "[%d]: %s(numerical rep: %d)\n", i, ppBuf[i] ? ppBuf[i] : "!NO MEMORY!", ( *pDictValues )[i] );
|
||||
}
|
||||
}
|
||||
|
||||
// free memory again
|
||||
for( i = 0; i < *pDictValCnt; i++ )
|
||||
{
|
||||
free( ppBuf[i] );
|
||||
}
|
||||
free( ppBuf );
|
||||
return funcResult;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void conditionalSetPropI( HOBJ hProp, int value, unsigned int silent )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
unsigned int dictValCount = 0;
|
||||
size_t i = 0;
|
||||
int* dictVals = NULL;
|
||||
TPROPHANDLING_ERROR result = PROPHANDLING_NO_ERROR;
|
||||
char bufName[BUF_SIZE_LARGE];
|
||||
char* pBufValue = 0;
|
||||
|
||||
if( ( result = readTranslationDictValuesI( hProp, &dictVals, &dictValCount, silent ) ) == PROPHANDLING_NO_ERROR )
|
||||
{
|
||||
for( i = 0; i < dictValCount; i++ )
|
||||
{
|
||||
if( dictVals[i] == value )
|
||||
{
|
||||
setPropI( hProp, value, 0 );
|
||||
memset( bufName, '\0', BUF_SIZE_LARGE );
|
||||
OBJ_GetName( hProp, bufName, BUF_SIZE_LARGE );
|
||||
getValueAsString( hProp, 0, &pBufValue, 0 );
|
||||
if( silent == 0 )
|
||||
{
|
||||
printf( "Property '%s' set to '%s'.\n", bufName, pBufValue );
|
||||
}
|
||||
free( pBufValue );
|
||||
break;
|
||||
}
|
||||
}
|
||||
free( dictVals );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "Failed to read translation dictionary from property. Error code: %d(%s).\n", result, DMR_ErrorCodeToString( result ) );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
int getDeviceFromUserInput( HDEV* phDevice, SUPPORTED_DEVICE_CHECK pSupportedDeviceCheckFn, unsigned int automaticallyUseGenICamInterface )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
TDMR_ERROR result = DMR_NO_ERROR;
|
||||
unsigned int i = 0;
|
||||
unsigned int deviceCount = 0;
|
||||
unsigned int deviceNumber = 0;
|
||||
HOBJ hPropSerial = INVALID_ID;
|
||||
HOBJ hPropProduct = INVALID_ID;
|
||||
HOBJ hPropInterfaceLayout = INVALID_ID;
|
||||
HOBJ hPropAcquisitionStartStopBehaviour = INVALID_ID;
|
||||
char* pSerialStringBuffer = NULL;
|
||||
char* pProductStringBuffer = NULL;
|
||||
|
||||
if( ( result = DMR_GetDeviceCount( &deviceCount ) ) != DMR_NO_ERROR )
|
||||
{
|
||||
printf( "DMR_GetDeviceCount failed (code: %d(%s))\n", result, DMR_ErrorCodeToString( result ) );
|
||||
END_APPLICATION;
|
||||
}
|
||||
|
||||
if( deviceCount == 0 )
|
||||
{
|
||||
printf( "No compliant device detected.\n" );
|
||||
END_APPLICATION;
|
||||
}
|
||||
|
||||
printf( "%d compliant devices detected.\n", deviceCount );
|
||||
for( i = 0; i < deviceCount; i++ )
|
||||
{
|
||||
// try to get access to the device
|
||||
if( ( result = DMR_GetDevice( phDevice, dmdsmSerial, "*", i, '*' ) ) != DMR_NO_ERROR )
|
||||
{
|
||||
printf( "DMR_GetDevice(%d) failed (code: %d(%s))\n", i, result, DMR_ErrorCodeToString( result ) );
|
||||
END_APPLICATION;
|
||||
}
|
||||
|
||||
if( ( hPropSerial = getDeviceProp( *phDevice, "Serial" ) ) == INVALID_ID )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
getStringValue( hPropSerial, &pSerialStringBuffer, 0 );
|
||||
if( !pSupportedDeviceCheckFn || pSupportedDeviceCheckFn( *phDevice ) )
|
||||
{
|
||||
if( ( hPropProduct = getDeviceProp( *phDevice, "Product" ) ) == INVALID_ID )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
getStringValue( hPropProduct, &pProductStringBuffer, 0 );
|
||||
printf( "[%d] %s (%s", i, pSerialStringBuffer, pProductStringBuffer );
|
||||
if( ( hPropInterfaceLayout = getDeviceProp( *phDevice, "InterfaceLayout" ) ) != INVALID_ID )
|
||||
{
|
||||
char* pStringBuffer = NULL;
|
||||
getValueAsString( hPropInterfaceLayout, NULL, &pStringBuffer, 0 );
|
||||
if( automaticallyUseGenICamInterface != 0 )
|
||||
{
|
||||
conditionalSetPropI( hPropInterfaceLayout, dilGenICam, 1 );
|
||||
}
|
||||
printf( ", interface layout: %s", pStringBuffer );
|
||||
free( pStringBuffer );
|
||||
}
|
||||
|
||||
if( ( hPropAcquisitionStartStopBehaviour = getDeviceProp( *phDevice, "AcquisitionStartStopBehaviour" ) ) != INVALID_ID )
|
||||
{
|
||||
char* pStringBuffer = NULL;
|
||||
conditionalSetPropI( hPropAcquisitionStartStopBehaviour, assbUser, 1 );
|
||||
getValueAsString( hPropAcquisitionStartStopBehaviour, NULL, &pStringBuffer, 0 );
|
||||
printf( ", acquisition start/stop behaviour: %s", pStringBuffer );
|
||||
free( pStringBuffer );
|
||||
}
|
||||
printf( ")\n" );
|
||||
free( pProductStringBuffer );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "%s is not supported by this application.\n", pSerialStringBuffer );
|
||||
}
|
||||
free( pSerialStringBuffer );
|
||||
}
|
||||
|
||||
printf( "Please enter the number in brackets followed by [ENTER] to open it: " );
|
||||
deviceNumber = getIntValFromSTDIn();
|
||||
// remove the '\n' from the stream
|
||||
fgetc( stdin );
|
||||
|
||||
// try to get access to the selected device
|
||||
if( ( result = DMR_GetDevice( phDevice, dmdsmSerial, "*", deviceNumber, '*' ) ) != DMR_NO_ERROR )
|
||||
{
|
||||
printf( "DMR_GetDevice(%d) failed (code: %d(%s))\n", deviceNumber, result, DMR_ErrorCodeToString( result ) );
|
||||
printf( "DMR_Close: %d\n", DMR_Close() );
|
||||
END_APPLICATION;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
static unsigned int isFeatureFlagSet( HOBJ hObj, TComponentFlag flag )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
TComponentFlag flags;
|
||||
|
||||
if( ( hObj == INVALID_ID ) ||
|
||||
( OBJ_GetFlags( hObj, &flags ) != PROPHANDLING_NO_ERROR ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ( ( flags & flag ) != 0 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned int isFeatureReadable( HOBJ hObj )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return isFeatureFlagSet( hObj, cfReadAccess );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned int isFeatureWriteable( HOBJ hObj )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return isFeatureFlagSet( hObj, cfWriteAccess );
|
||||
}
|
||||
|
||||
#if defined(linux) || defined(__linux) || defined(__linux__)
|
||||
# include <sys/types.h>
|
||||
# include <unistd.h>
|
||||
//-----------------------------------------------------------------------------
|
||||
// returns 0 if timeout, else 1
|
||||
unsigned waitForInput( int maxWait_sec, int fd )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
fd_set rfds;
|
||||
struct timeval tv;
|
||||
|
||||
FD_ZERO( &rfds );
|
||||
FD_SET( fd, &rfds );
|
||||
|
||||
tv.tv_sec = maxWait_sec ;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
return select( fd + 1, &rfds, NULL, NULL, &tv );
|
||||
}
|
||||
#endif // #if defined(linux) || defined(__linux) || defined(__linux__)
|
@ -0,0 +1,71 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef exampleHelper_CH
|
||||
#define exampleHelper_CH exampleHelper_CH
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <mvDeviceManager/Include/mvDeviceManager.h>
|
||||
|
||||
#define END_APPLICATION \
|
||||
printf( "Press [ENTER] to end the application.\n" ); \
|
||||
return getchar() == EOF ? 2 : 1;
|
||||
|
||||
#if defined(linux) || defined(__linux) || defined(__linux__)
|
||||
unsigned waitForInput( int maxWait_sec, int fd );
|
||||
#endif // #if defined(linux) || defined(__linux) || defined(__linux__)
|
||||
|
||||
int getIntValFromSTDIn( void );
|
||||
int getPropI( HOBJ hProp, int index );
|
||||
void setPropI( HOBJ hProp, int value, int index );
|
||||
int64_type getPropI64( HOBJ hProp, int index );
|
||||
void setPropI64( HOBJ hProp, int64_type value, int index );
|
||||
void* getPropP( HOBJ hProp, int index );
|
||||
void setPropP( HOBJ hProp, void* value, int index );
|
||||
void setPropS( HOBJ hProp, const char* pVal, int index );
|
||||
|
||||
HOBJ getDriverList( HDRV hDrv, const char* pListName, const char* pAddListName, TDMR_ListType type );
|
||||
HOBJ getDriverProperty( HDRV hDrv, const char* pPropName, const char* pAddListName, TDMR_ListType type );
|
||||
HOBJ getDriverMethod( HDRV hDrv, const char* pMethodName, const char* pAddListName, TDMR_ListType type );
|
||||
HOBJ getDeviceProp( HDEV hDev, const char* pPropName );
|
||||
HOBJ getInfoProp( HDRV hDrv, const char* pPropName );
|
||||
HOBJ getIOSubSystemProp( HDRV hDrv, const char* pPropName );
|
||||
HOBJ getRequestCtrlProp( HDRV hDrv, const char* pRequestCtrlName, const char* pPropName );
|
||||
HOBJ getRequestProp( HDRV hDrv, int requestNr, const char* pPropName );
|
||||
HOBJ getSettingProp( HDRV hDrv, const char* pSettingName, const char* pPropName );
|
||||
HOBJ getSettingMethod( HDRV hDrv, const char* pSettingName, const char* pMethodName );
|
||||
HOBJ getStatisticProp( HDRV hDrv, const char* pPropName );
|
||||
HOBJ getSystemSettingProp( HDRV hDrv, const char* pPropName );
|
||||
|
||||
unsigned int isFeatureReadable( HOBJ hObj );
|
||||
unsigned int isFeatureWriteable( HOBJ hObj );
|
||||
|
||||
typedef unsigned int( *SUPPORTED_DEVICE_CHECK )( const HDEV );
|
||||
|
||||
int getDeviceFromUserInput( HDEV* phDevice, SUPPORTED_DEVICE_CHECK pSupportedDeviceCheckFn, unsigned int automaticallyUseGenICamInterface );
|
||||
/// \brief Reads the value of a feature as a string
|
||||
/// \note
|
||||
/// pBuf must be freed by the caller
|
||||
TPROPHANDLING_ERROR getStringValue( HOBJ hObj, char** pBuf, int index );
|
||||
/// \brief Reads the value of a feature as a string
|
||||
/// \note
|
||||
/// pBuf must be freed by the caller
|
||||
TPROPHANDLING_ERROR getValueAsString( HOBJ hObj, const char* pFormat, char** pBuf, int index );
|
||||
void modifyEnumPropertyI( HDRV hDrv, const char* pSettingName, const char* pPropName );
|
||||
/// \brief Shows how to read the translation dictionary of an integer property and returns all the
|
||||
/// integer values in the dictionary.
|
||||
///
|
||||
/// \note
|
||||
/// \a pDictValues must be freed by the caller.
|
||||
TPROPHANDLING_ERROR readTranslationDictValuesI( HOBJ hObj, int** pDictValues, unsigned int* pDictValCnt, unsigned int silent );
|
||||
/// \brief Sets an enumerated integer property to a certain value if this value is supported by
|
||||
/// the property.
|
||||
void conditionalSetPropI( HOBJ hObj, int value, unsigned int silent );
|
||||
|
||||
/// \brief Start the acquisition manually if this was requested(this is to prepare the driver for data capture and tell the device to start streaming data)
|
||||
///
|
||||
/// Whether this is needed or not depends on the property 'AcquisitionStartStopBehaviour' in the list referenced by 'HDEV'.
|
||||
void manuallyStartAcquisitionIfNeeded( HDRV hDrv );
|
||||
/// \brief Stop the acquisition manually if this was requested.
|
||||
///
|
||||
/// Whether this is needed or not depends on the property 'AcquisitionStartStopBehaviour' in the list referenced by 'HDEV'.
|
||||
void manuallyStopAcquisitionIfNeeded( HDRV hDrv );
|
||||
|
||||
#endif // exampleHelper_CH
|
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
@ -0,0 +1,3 @@
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400) // is at least VC 2005 compiler?
|
||||
# pragma warning( pop )
|
||||
#endif
|
@ -0,0 +1,7 @@
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400) // is at least VC 2005 compiler?
|
||||
# pragma warning( push )
|
||||
# pragma warning( disable : 4127 ) // 'conditional expression is constant'
|
||||
# pragma warning( disable : 4244 ) // 'conversion from 'Bla' to 'Blub', possible loss of data
|
||||
# pragma warning( disable : 4251 ) // 'class 'Bla' needs to have dll-interface to be used by clients of class 'Blub''
|
||||
# pragma warning( disable : 4800 ) // 'int' : forcing value to bool 'true' or 'false' (performance warning)
|
||||
#endif
|
@ -0,0 +1,409 @@
|
||||
#include "ProxyResolver.h"
|
||||
|
||||
#if _WIN32_WINNT < 0x0602 // This stuff became available with Windows 8
|
||||
# define WINHTTP_CALLBACK_STATUS_GETPROXYFORURL_COMPLETE 0x01000000
|
||||
# define WINHTTP_CALLBACK_FLAG_GETPROXYFORURL_COMPLETE WINHTTP_CALLBACK_STATUS_GETPROXYFORURL_COMPLETE
|
||||
# define API_GET_PROXY_FOR_URL (6)
|
||||
#endif // #if _WIN32_WINNT < _WIN32_WINNT_WIN8
|
||||
|
||||
PFNWINHTTPGETPROXYFORURLEX ProxyResolver::s_pfnWinhttpGetProxyForUrlEx = NULL;
|
||||
PFNWINHTTPFREEPROXYLIST ProxyResolver::s_pfnWinhttpFreeProxyList = NULL;
|
||||
PFNWINHTTPCREATEPROXYRESOLVER ProxyResolver::s_pfnWinhttpCreateProxyResolver = NULL;
|
||||
PFNWINHTTPGETPROXYRESULT ProxyResolver::s_pfnWinhttpGetProxyResult = NULL;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
ProxyResolver::ProxyResolver() : m_fInit( FALSE ), m_fExtendedAPI( FALSE ), m_dwError( ERROR_SUCCESS ), m_hEvent( 0 )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
ZeroMemory( &m_wprProxyResult, sizeof( WINHTTP_PROXY_RESULT ) );
|
||||
ZeroMemory( &m_wpiProxyInfo, sizeof( WINHTTP_PROXY_INFO ) );
|
||||
|
||||
HMODULE hWinhttp = GetModuleHandle( L"winhttp.dll" );
|
||||
if( hWinhttp != NULL )
|
||||
{
|
||||
s_pfnWinhttpGetProxyForUrlEx = ( PFNWINHTTPGETPROXYFORURLEX )GetProcAddress( hWinhttp, "WinHttpGetProxyForUrlEx" );
|
||||
s_pfnWinhttpFreeProxyList = ( PFNWINHTTPFREEPROXYLIST )GetProcAddress( hWinhttp, "WinHttpFreeProxyResult" );
|
||||
s_pfnWinhttpCreateProxyResolver = ( PFNWINHTTPCREATEPROXYRESOLVER )GetProcAddress( hWinhttp, "WinHttpCreateProxyResolver" );
|
||||
s_pfnWinhttpGetProxyResult = ( PFNWINHTTPGETPROXYRESULT )GetProcAddress( hWinhttp, "WinHttpGetProxyResult" );
|
||||
}
|
||||
m_fExtendedAPI = s_pfnWinhttpGetProxyForUrlEx && s_pfnWinhttpFreeProxyList && s_pfnWinhttpCreateProxyResolver && s_pfnWinhttpGetProxyResult;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
ProxyResolver::~ProxyResolver()
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( m_wpiProxyInfo.lpszProxy != NULL )
|
||||
{
|
||||
GlobalFree( m_wpiProxyInfo.lpszProxy );
|
||||
}
|
||||
|
||||
if( m_wpiProxyInfo.lpszProxyBypass != NULL )
|
||||
{
|
||||
GlobalFree( m_wpiProxyInfo.lpszProxyBypass );
|
||||
}
|
||||
|
||||
if( m_fExtendedAPI )
|
||||
{
|
||||
s_pfnWinhttpFreeProxyList( &m_wprProxyResult );
|
||||
}
|
||||
|
||||
if( m_hEvent != NULL )
|
||||
{
|
||||
CloseHandle( m_hEvent );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
BOOL ProxyResolver::IsRecoverableAutoProxyError( _In_ DWORD dwError )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
switch( dwError )
|
||||
{
|
||||
case ERROR_SUCCESS:
|
||||
case ERROR_INVALID_PARAMETER:
|
||||
case ERROR_WINHTTP_AUTO_PROXY_SERVICE_ERROR:
|
||||
case ERROR_WINHTTP_AUTODETECTION_FAILED:
|
||||
case ERROR_WINHTTP_BAD_AUTO_PROXY_SCRIPT:
|
||||
case ERROR_WINHTTP_LOGIN_FAILURE:
|
||||
case ERROR_WINHTTP_OPERATION_CANCELLED:
|
||||
case ERROR_WINHTTP_TIMEOUT:
|
||||
case ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT:
|
||||
case ERROR_WINHTTP_UNRECOGNIZED_SCHEME:
|
||||
return TRUE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
VOID CALLBACK ProxyResolver::GetProxyCallBack( _In_ HINTERNET hResolver, _In_ DWORD_PTR dwContext, _In_ DWORD dwInternetStatus, _In_ PVOID pvStatusInformation, _In_ DWORD /*dwStatusInformationLength*/ )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
ProxyResolver* pProxyResolver = ( ProxyResolver* )dwContext;
|
||||
if( ( dwInternetStatus != WINHTTP_CALLBACK_STATUS_GETPROXYFORURL_COMPLETE &&
|
||||
dwInternetStatus != WINHTTP_CALLBACK_STATUS_REQUEST_ERROR ) ||
|
||||
pProxyResolver == NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( dwInternetStatus == WINHTTP_CALLBACK_STATUS_REQUEST_ERROR )
|
||||
{
|
||||
WINHTTP_ASYNC_RESULT* pAsyncResult = ( WINHTTP_ASYNC_RESULT* )pvStatusInformation;
|
||||
|
||||
if( pAsyncResult->dwResult != API_GET_PROXY_FOR_URL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pProxyResolver->m_dwError = pAsyncResult->dwError;
|
||||
}
|
||||
else if( dwInternetStatus == WINHTTP_CALLBACK_STATUS_GETPROXYFORURL_COMPLETE )
|
||||
{
|
||||
pProxyResolver->m_dwError = s_pfnWinhttpGetProxyResult( hResolver, &pProxyResolver->m_wprProxyResult );
|
||||
}
|
||||
|
||||
if( hResolver != NULL )
|
||||
{
|
||||
WinHttpCloseHandle( hResolver );
|
||||
hResolver = NULL;
|
||||
}
|
||||
|
||||
SetEvent( pProxyResolver->m_hEvent );
|
||||
}
|
||||
|
||||
#define CLOSE_RESOLVER_HANDLE_AND_RETURN_ERROR_CODE(HRESOLVER, ERROR_CODE) \
|
||||
if( HRESOLVER != NULL ) \
|
||||
{ \
|
||||
WinHttpCloseHandle( HRESOLVER ); \
|
||||
} \
|
||||
return ERROR_CODE
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
DWORD ProxyResolver::GetProxyForUrlEx( _In_ HINTERNET hSession, _In_z_ PCWSTR pwszUrl, _In_ WINHTTP_AUTOPROXY_OPTIONS* pAutoProxyOptions )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
// Create proxy resolver handle. It's best to close the handle during call back.
|
||||
HINTERNET hResolver = NULL;
|
||||
DWORD dwError = s_pfnWinhttpCreateProxyResolver( hSession, &hResolver );
|
||||
if( dwError != ERROR_SUCCESS )
|
||||
{
|
||||
CLOSE_RESOLVER_HANDLE_AND_RETURN_ERROR_CODE( hResolver, dwError );
|
||||
}
|
||||
|
||||
// Sets up a callback function that WinHTTP can call as proxy results are resolved.
|
||||
WINHTTP_STATUS_CALLBACK wscCallback = WinHttpSetStatusCallback( hResolver, GetProxyCallBack, WINHTTP_CALLBACK_FLAG_REQUEST_ERROR | WINHTTP_CALLBACK_FLAG_GETPROXYFORURL_COMPLETE, 0 );
|
||||
if( wscCallback == WINHTTP_INVALID_STATUS_CALLBACK )
|
||||
{
|
||||
dwError = GetLastError();
|
||||
CLOSE_RESOLVER_HANDLE_AND_RETURN_ERROR_CODE( hResolver, dwError );
|
||||
}
|
||||
|
||||
// The extended API works in asynchronous mode, therefore wait until the
|
||||
// results are set in the call back function.
|
||||
dwError = s_pfnWinhttpGetProxyForUrlEx( hResolver, pwszUrl, pAutoProxyOptions, ( DWORD_PTR )this );
|
||||
if( dwError != ERROR_IO_PENDING )
|
||||
{
|
||||
CLOSE_RESOLVER_HANDLE_AND_RETURN_ERROR_CODE( hResolver, dwError );
|
||||
}
|
||||
|
||||
// The resolver handle will get closed in the callback and cannot be used any longer.
|
||||
hResolver = NULL;
|
||||
dwError = WaitForSingleObjectEx( m_hEvent, INFINITE, FALSE );
|
||||
if( dwError != WAIT_OBJECT_0 )
|
||||
{
|
||||
return GetLastError();
|
||||
}
|
||||
return m_dwError;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
_Success_( return == ERROR_SUCCESS ) DWORD ProxyResolver::GetProxyForAutoSettings( _In_ HINTERNET hSession, _In_z_ PCWSTR pwszUrl, _In_opt_z_ PCWSTR pwszAutoConfigUrl, _Outptr_result_maybenull_ PWSTR* ppwszProxy, _Outptr_result_maybenull_ PWSTR* ppwszProxyBypass )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
DWORD dwError = ERROR_SUCCESS;
|
||||
WINHTTP_AUTOPROXY_OPTIONS waoOptions = {};
|
||||
WINHTTP_PROXY_INFO wpiProxyInfo = {};
|
||||
|
||||
*ppwszProxy = NULL;
|
||||
*ppwszProxyBypass = NULL;
|
||||
|
||||
if( pwszAutoConfigUrl )
|
||||
{
|
||||
waoOptions.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
|
||||
waoOptions.lpszAutoConfigUrl = pwszAutoConfigUrl;
|
||||
}
|
||||
else
|
||||
{
|
||||
waoOptions.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
|
||||
waoOptions.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A;
|
||||
}
|
||||
|
||||
// First call with no autologon. Autologon prevents the
|
||||
// session (in proc) or autoproxy service (out of proc) from caching
|
||||
// the proxy script. This causes repetitive network traffic, so it is
|
||||
// best not to do autologon unless it is required according to the
|
||||
// result of WinHttpGetProxyForUrl.
|
||||
// This applies to both WinHttpGetProxyForUrl and WinhttpGetProxyForUrlEx.
|
||||
if( m_fExtendedAPI )
|
||||
{
|
||||
m_hEvent = CreateEventEx( NULL, NULL, 0, EVENT_ALL_ACCESS );
|
||||
if( m_hEvent == NULL )
|
||||
{
|
||||
dwError = GetLastError();
|
||||
goto quit;
|
||||
}
|
||||
|
||||
dwError = GetProxyForUrlEx( hSession, pwszUrl, &waoOptions );
|
||||
if( dwError != ERROR_WINHTTP_LOGIN_FAILURE )
|
||||
{
|
||||
// Unless we need to retry with auto-logon exit the function with the
|
||||
// result, on success the proxy list will be stored in m_wprProxyResult
|
||||
// by GetProxyCallBack.
|
||||
goto quit;
|
||||
}
|
||||
|
||||
// Enable autologon if challenged.
|
||||
waoOptions.fAutoLogonIfChallenged = TRUE;
|
||||
dwError = GetProxyForUrlEx( hSession, pwszUrl, &waoOptions );
|
||||
goto quit;
|
||||
}
|
||||
|
||||
if( !WinHttpGetProxyForUrl( hSession, pwszUrl, &waoOptions, &wpiProxyInfo ) )
|
||||
{
|
||||
dwError = GetLastError();
|
||||
if( dwError != ERROR_WINHTTP_LOGIN_FAILURE )
|
||||
{
|
||||
goto quit;
|
||||
}
|
||||
|
||||
// Enable autologon if challenged.
|
||||
dwError = ERROR_SUCCESS;
|
||||
waoOptions.fAutoLogonIfChallenged = TRUE;
|
||||
if( !WinHttpGetProxyForUrl( hSession, pwszUrl, &waoOptions, &wpiProxyInfo ) )
|
||||
{
|
||||
dwError = GetLastError();
|
||||
goto quit;
|
||||
}
|
||||
}
|
||||
|
||||
*ppwszProxy = wpiProxyInfo.lpszProxy;
|
||||
wpiProxyInfo.lpszProxy = NULL;
|
||||
|
||||
*ppwszProxyBypass = wpiProxyInfo.lpszProxyBypass;
|
||||
wpiProxyInfo.lpszProxyBypass = NULL;
|
||||
|
||||
quit:
|
||||
|
||||
if( wpiProxyInfo.lpszProxy )
|
||||
{
|
||||
GlobalFree( wpiProxyInfo.lpszProxy );
|
||||
wpiProxyInfo.lpszProxy = NULL;
|
||||
}
|
||||
|
||||
if( wpiProxyInfo.lpszProxyBypass )
|
||||
{
|
||||
GlobalFree( wpiProxyInfo.lpszProxyBypass );
|
||||
wpiProxyInfo.lpszProxyBypass = NULL;
|
||||
}
|
||||
|
||||
return dwError;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
DWORD ProxyResolver::ResolveProxy( _In_ HINTERNET hSession, _In_z_ PCWSTR pwszUrl )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
DWORD dwError = ERROR_SUCCESS;
|
||||
WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ProxyConfig = {};
|
||||
PWSTR pwszProxy = NULL;
|
||||
PWSTR pwszProxyBypass = NULL;
|
||||
BOOL fFailOverValid = FALSE;
|
||||
|
||||
if( m_fInit )
|
||||
{
|
||||
dwError = ERROR_INVALID_OPERATION;
|
||||
goto quit;
|
||||
}
|
||||
|
||||
if( !WinHttpGetIEProxyConfigForCurrentUser( &ProxyConfig ) )
|
||||
{
|
||||
dwError = GetLastError();
|
||||
if( dwError != ERROR_FILE_NOT_FOUND )
|
||||
{
|
||||
goto quit;
|
||||
}
|
||||
|
||||
// No IE proxy settings found, just do autodetect.
|
||||
ProxyConfig.fAutoDetect = TRUE;
|
||||
dwError = ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
// Begin processing the proxy settings in the following order:
|
||||
// 1) Auto-Detect if configured.
|
||||
// 2) Auto-Config URL if configured.
|
||||
// 3) Static Proxy Settings if configured.
|
||||
//
|
||||
// Once any of these methods succeed in finding a proxy we are finished.
|
||||
// In the event one mechanism fails with an expected error code it is
|
||||
// required to fall back to the next mechanism. If the request fails
|
||||
// after exhausting all detected proxies, there should be no attempt
|
||||
// to discover additional proxies.
|
||||
if( ProxyConfig.fAutoDetect )
|
||||
{
|
||||
fFailOverValid = TRUE;
|
||||
// Detect Proxy Settings.
|
||||
dwError = GetProxyForAutoSettings( hSession, pwszUrl, NULL, &pwszProxy, &pwszProxyBypass );
|
||||
if( dwError == ERROR_SUCCESS )
|
||||
{
|
||||
goto commit;
|
||||
}
|
||||
|
||||
if( !IsRecoverableAutoProxyError( dwError ) )
|
||||
{
|
||||
goto quit;
|
||||
}
|
||||
|
||||
// Fall back to Autoconfig URL or Static settings. An application can
|
||||
// optionally take some action such as logging, or creating a mechanism
|
||||
// to expose multiple error codes in the class.
|
||||
dwError = ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
if( ProxyConfig.lpszAutoConfigUrl )
|
||||
{
|
||||
fFailOverValid = TRUE;
|
||||
// Run autoproxy with AutoConfig URL.
|
||||
dwError = GetProxyForAutoSettings( hSession, pwszUrl, ProxyConfig.lpszAutoConfigUrl, &pwszProxy, &pwszProxyBypass );
|
||||
if( dwError == ERROR_SUCCESS )
|
||||
{
|
||||
goto commit;
|
||||
}
|
||||
|
||||
if( !IsRecoverableAutoProxyError( dwError ) )
|
||||
{
|
||||
goto quit;
|
||||
}
|
||||
|
||||
// Fall back to Static Settings. An application can optionally take some
|
||||
// action such as logging, or creating a mechanism to to expose multiple
|
||||
// error codes in the class.
|
||||
dwError = ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
fFailOverValid = FALSE;
|
||||
// Static Proxy Config. Failover is not valid for static proxy since
|
||||
// it is always either a single proxy or a list containing protocol
|
||||
// specific proxies such as "proxy" or http=httpproxy;https=sslproxy
|
||||
pwszProxy = ProxyConfig.lpszProxy;
|
||||
ProxyConfig.lpszProxy = NULL;
|
||||
|
||||
pwszProxyBypass = ProxyConfig.lpszProxyBypass;
|
||||
ProxyConfig.lpszProxyBypass = NULL;
|
||||
|
||||
commit:
|
||||
|
||||
if( pwszProxy == NULL )
|
||||
{
|
||||
m_wpiProxyInfo.dwAccessType = WINHTTP_ACCESS_TYPE_NO_PROXY;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_wpiProxyInfo.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
|
||||
}
|
||||
|
||||
m_wpiProxyInfo.lpszProxy = pwszProxy;
|
||||
pwszProxy = NULL;
|
||||
|
||||
m_wpiProxyInfo.lpszProxyBypass = pwszProxyBypass;
|
||||
pwszProxyBypass = NULL;
|
||||
|
||||
m_fInit = TRUE;
|
||||
|
||||
quit:
|
||||
|
||||
if( pwszProxy != NULL )
|
||||
{
|
||||
GlobalFree( pwszProxy );
|
||||
pwszProxy = NULL;
|
||||
}
|
||||
|
||||
if( pwszProxyBypass != NULL )
|
||||
{
|
||||
GlobalFree( pwszProxyBypass );
|
||||
pwszProxyBypass = NULL;
|
||||
}
|
||||
|
||||
if( ProxyConfig.lpszAutoConfigUrl != NULL )
|
||||
{
|
||||
GlobalFree( ProxyConfig.lpszAutoConfigUrl );
|
||||
ProxyConfig.lpszAutoConfigUrl = NULL;
|
||||
}
|
||||
|
||||
if( ProxyConfig.lpszProxy != NULL )
|
||||
{
|
||||
GlobalFree( ProxyConfig.lpszProxy );
|
||||
ProxyConfig.lpszProxy = NULL;
|
||||
}
|
||||
|
||||
if( ProxyConfig.lpszProxyBypass != NULL )
|
||||
{
|
||||
GlobalFree( ProxyConfig.lpszProxyBypass );
|
||||
ProxyConfig.lpszProxyBypass = NULL;
|
||||
}
|
||||
|
||||
return dwError;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
const WINHTTP_PROXY_RESULT_ENTRY* ProxyResolver::GetProxySetting( const DWORD index ) const
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( index < m_wprProxyResult.cEntries )
|
||||
{
|
||||
return &m_wprProxyResult.pEntries[index];
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
#include <winhttp.h>
|
||||
|
||||
#if _WIN32_WINNT < 0x0602 // This stuff became available with Windows 8
|
||||
typedef struct _WINHTTP_PROXY_RESULT_ENTRY
|
||||
{
|
||||
BOOL fProxy; // Is this a proxy or DIRECT?
|
||||
BOOL fBypass; // If DIRECT, is it bypassing a proxy (intranet) or is all traffic DIRECT (internet)
|
||||
INTERNET_SCHEME ProxyScheme; // The scheme of the proxy, SOCKS, HTTP (CERN Proxy), HTTPS (SSL through Proxy)
|
||||
PWSTR pwszProxy; // Hostname of the proxy.
|
||||
INTERNET_PORT ProxyPort; // Port of the proxy.
|
||||
} WINHTTP_PROXY_RESULT_ENTRY;
|
||||
|
||||
typedef struct _WINHTTP_PROXY_RESULT
|
||||
{
|
||||
DWORD cEntries;
|
||||
WINHTTP_PROXY_RESULT_ENTRY* pEntries;
|
||||
} WINHTTP_PROXY_RESULT;
|
||||
#endif // #if _WIN32_WINNT < 0x0602
|
||||
|
||||
typedef DWORD ( WINAPI* PFNWINHTTPGETPROXYFORURLEX )( HINTERNET, PCWSTR, WINHTTP_AUTOPROXY_OPTIONS*, DWORD_PTR );
|
||||
typedef DWORD ( WINAPI* PFNWINHTTPFREEPROXYLIST )( WINHTTP_PROXY_RESULT* );
|
||||
typedef DWORD ( WINAPI* PFNWINHTTPCREATEPROXYRESOLVER )( HINTERNET, HINTERNET* );
|
||||
typedef DWORD ( WINAPI* PFNWINHTTPGETPROXYRESULT )( HINTERNET, WINHTTP_PROXY_RESULT* );
|
||||
|
||||
class ProxyResolver
|
||||
{
|
||||
BOOL m_fInit;
|
||||
BOOL m_fExtendedAPI;
|
||||
DWORD m_dwError;
|
||||
HANDLE m_hEvent;
|
||||
WINHTTP_PROXY_INFO m_wpiProxyInfo;
|
||||
WINHTTP_PROXY_RESULT m_wprProxyResult;
|
||||
|
||||
BOOL IsRecoverableAutoProxyError( _In_ DWORD dwError );
|
||||
VOID static CALLBACK GetProxyCallBack( _In_ HINTERNET hResolver, _In_ DWORD_PTR dwContext, _In_ DWORD dwInternetStatus, _In_ PVOID pvStatusInformation, _In_ DWORD dwStatusInformationLength );
|
||||
DWORD GetProxyForUrlEx( _In_ HINTERNET hSession, _In_z_ PCWSTR pwszUrl, _In_ WINHTTP_AUTOPROXY_OPTIONS* pAutoProxyOptions );
|
||||
_Success_( return == ERROR_SUCCESS ) DWORD GetProxyForAutoSettings( _In_ HINTERNET hSession, _In_z_ PCWSTR pwszUrl, _In_opt_z_ PCWSTR pwszAutoConfigUrl, _Outptr_result_maybenull_ PWSTR* ppwszProxy, _Outptr_result_maybenull_ PWSTR* ppwszProxyBypass );
|
||||
|
||||
static PFNWINHTTPGETPROXYFORURLEX s_pfnWinhttpGetProxyForUrlEx;
|
||||
static PFNWINHTTPFREEPROXYLIST s_pfnWinhttpFreeProxyList;
|
||||
static PFNWINHTTPCREATEPROXYRESOLVER s_pfnWinhttpCreateProxyResolver;
|
||||
static PFNWINHTTPGETPROXYRESULT s_pfnWinhttpGetProxyResult;
|
||||
|
||||
public:
|
||||
ProxyResolver();
|
||||
~ProxyResolver();
|
||||
|
||||
DWORD ResolveProxy( _In_ HINTERNET hSession, _In_z_ PCWSTR pwszUrl );
|
||||
const WINHTTP_PROXY_RESULT_ENTRY* GetProxySetting( const DWORD index ) const;
|
||||
};
|
@ -0,0 +1,232 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "../ProxyResolverContext.h"
|
||||
#include "ProxyResolver.h"
|
||||
#include <lmcons.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
//=============================================================================
|
||||
//================= Implementation ProxyResolverContextImpl ===================
|
||||
//=============================================================================
|
||||
//-----------------------------------------------------------------------------
|
||||
struct ProxyResolverContextImpl
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
HINTERNET hProxyResolveSession;
|
||||
ProxyResolver* pProxyResolver;
|
||||
explicit ProxyResolverContextImpl( const wstring& userAgent ) : hProxyResolveSession( 0 ), pProxyResolver( 0 )
|
||||
{
|
||||
hProxyResolveSession = WinHttpOpen( userAgent.c_str(), WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, WINHTTP_FLAG_ASYNC );
|
||||
if( hProxyResolveSession )
|
||||
{
|
||||
pProxyResolver = new ProxyResolver();
|
||||
}
|
||||
}
|
||||
~ProxyResolverContextImpl()
|
||||
{
|
||||
delete pProxyResolver;
|
||||
if( hProxyResolveSession )
|
||||
{
|
||||
WinHttpCloseHandle( hProxyResolveSession );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
//================= Implementation ProxyResolverContext =======================
|
||||
//=============================================================================
|
||||
//-----------------------------------------------------------------------------
|
||||
ProxyResolverContext::ProxyResolverContext( const wstring& userAgent, const wstring& url ) : pImpl_( new ProxyResolverContextImpl( userAgent ) )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( pImpl_->pProxyResolver )
|
||||
{
|
||||
pImpl_->pProxyResolver->ResolveProxy( pImpl_->hProxyResolveSession, url.c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
ProxyResolverContext::~ProxyResolverContext()
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
delete pImpl_;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
wstring ProxyResolverContext::GetProxy( unsigned int index ) const
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
const WINHTTP_PROXY_RESULT_ENTRY* pProxyData = pImpl_->pProxyResolver->GetProxySetting( index );
|
||||
return ( pProxyData && pProxyData->pwszProxy ) ? wstring( pProxyData->pwszProxy ) : wstring();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned int ProxyResolverContext::GetProxyPort( unsigned int index ) const
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
const WINHTTP_PROXY_RESULT_ENTRY* pProxyData = pImpl_->pProxyResolver->GetProxySetting( index );
|
||||
return pProxyData ? pProxyData->ProxyPort : 0;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//================= Implementation helper functions ===========================
|
||||
//=============================================================================
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \brief This function checks the token of the calling thread to see if the caller
|
||||
/// belongs to the Administrators group.
|
||||
/**
|
||||
* \return
|
||||
- true if the caller is an administrator on the local machine.
|
||||
- false otherwise
|
||||
*/
|
||||
bool IsCurrentUserLocalAdministrator( void )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
BOOL fReturn = FALSE;
|
||||
PACL pACL = NULL;
|
||||
PSID psidAdmin = NULL;
|
||||
HANDLE hToken = NULL;
|
||||
HANDLE hImpersonationToken = NULL;
|
||||
PSECURITY_DESCRIPTOR psdAdmin = NULL;
|
||||
|
||||
|
||||
// Determine if the current thread is running as a user that is a member of
|
||||
// the local admins group. To do this, create a security descriptor that
|
||||
// has a DACL which has an ACE that allows only local administrators access.
|
||||
// Then, call AccessCheck with the current thread's token and the security
|
||||
// descriptor. It will say whether the user could access an object if it
|
||||
// had that security descriptor. Note: you do not need to actually create
|
||||
// the object. Just checking access against the security descriptor alone
|
||||
// will be sufficient.
|
||||
const DWORD ACCESS_READ = 1;
|
||||
const DWORD ACCESS_WRITE = 2;
|
||||
|
||||
__try
|
||||
{
|
||||
// AccessCheck() requires an impersonation token. We first get a primary
|
||||
// token and then create a duplicate impersonation token. The
|
||||
// impersonation token is not actually assigned to the thread, but is
|
||||
// used in the call to AccessCheck. Thus, this function itself never
|
||||
// impersonates, but does use the identity of the thread. If the thread
|
||||
// was impersonating already, this function uses that impersonation context.
|
||||
if( !OpenThreadToken( GetCurrentThread(), TOKEN_DUPLICATE | TOKEN_QUERY, TRUE, &hToken ) )
|
||||
{
|
||||
if( GetLastError() != ERROR_NO_TOKEN )
|
||||
{
|
||||
__leave;
|
||||
}
|
||||
|
||||
if( !OpenProcessToken( GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY, &hToken ) )
|
||||
{
|
||||
__leave;
|
||||
}
|
||||
}
|
||||
|
||||
if( !DuplicateToken ( hToken, SecurityImpersonation, &hImpersonationToken ) )
|
||||
{
|
||||
__leave;
|
||||
}
|
||||
|
||||
// Create the binary representation of the well-known SID that
|
||||
// represents the local administrators group. Then create the security
|
||||
// descriptor and DACL with an ACE that allows only local admins access.
|
||||
// After that, perform the access check. This will determine whether
|
||||
// the current user is a local admin.
|
||||
SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY;
|
||||
if( !AllocateAndInitializeSid( &SystemSidAuthority, 2,
|
||||
SECURITY_BUILTIN_DOMAIN_RID,
|
||||
DOMAIN_ALIAS_RID_ADMINS,
|
||||
0, 0, 0, 0, 0, 0, &psidAdmin ) )
|
||||
{
|
||||
__leave;
|
||||
}
|
||||
|
||||
psdAdmin = LocalAlloc( LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH );
|
||||
if( psdAdmin == NULL )
|
||||
{
|
||||
__leave;
|
||||
}
|
||||
|
||||
if( !InitializeSecurityDescriptor( psdAdmin, SECURITY_DESCRIPTOR_REVISION ) )
|
||||
{
|
||||
__leave;
|
||||
}
|
||||
|
||||
// Compute size needed for the ACL.
|
||||
const DWORD dwACLSize = sizeof( ACL ) + sizeof( ACCESS_ALLOWED_ACE ) + GetLengthSid( psidAdmin ) - sizeof( DWORD );
|
||||
pACL = ( PACL )LocalAlloc( LPTR, dwACLSize );
|
||||
if( pACL == NULL )
|
||||
{
|
||||
__leave;
|
||||
}
|
||||
|
||||
if( !InitializeAcl( pACL, dwACLSize, ACL_REVISION2 ) )
|
||||
{
|
||||
__leave;
|
||||
}
|
||||
|
||||
if( !AddAccessAllowedAce( pACL, ACL_REVISION2, ACCESS_READ | ACCESS_WRITE, psidAdmin ) )
|
||||
{
|
||||
__leave;
|
||||
}
|
||||
|
||||
if( !SetSecurityDescriptorDacl( psdAdmin, TRUE, pACL, FALSE ) )
|
||||
{
|
||||
__leave;
|
||||
}
|
||||
|
||||
// AccessCheck validates a security descriptor somewhat; set the group
|
||||
// and owner so that enough of the security descriptor is filled out to
|
||||
// make AccessCheck happy.
|
||||
SetSecurityDescriptorGroup( psdAdmin, psidAdmin, FALSE );
|
||||
SetSecurityDescriptorOwner( psdAdmin, psidAdmin, FALSE );
|
||||
|
||||
if( !IsValidSecurityDescriptor( psdAdmin ) )
|
||||
{
|
||||
__leave;
|
||||
}
|
||||
|
||||
// Initialize GenericMapping structure even though you do not use generic rights.
|
||||
GENERIC_MAPPING GenericMapping;
|
||||
GenericMapping.GenericRead = ACCESS_READ;
|
||||
GenericMapping.GenericWrite = ACCESS_WRITE;
|
||||
GenericMapping.GenericExecute = 0;
|
||||
GenericMapping.GenericAll = ACCESS_READ | ACCESS_WRITE;
|
||||
DWORD dwStructureSize = sizeof( PRIVILEGE_SET );
|
||||
DWORD dwStatus;
|
||||
PRIVILEGE_SET ps;
|
||||
if( !AccessCheck( psdAdmin, hImpersonationToken, ACCESS_READ,
|
||||
&GenericMapping, &ps, &dwStructureSize, &dwStatus,
|
||||
&fReturn ) )
|
||||
{
|
||||
fReturn = FALSE;
|
||||
__leave;
|
||||
}
|
||||
}
|
||||
__finally
|
||||
{
|
||||
if( pACL )
|
||||
{
|
||||
LocalFree( pACL );
|
||||
}
|
||||
if( psdAdmin )
|
||||
{
|
||||
LocalFree( psdAdmin );
|
||||
}
|
||||
if( psidAdmin )
|
||||
{
|
||||
FreeSid( psidAdmin );
|
||||
}
|
||||
if( hImpersonationToken )
|
||||
{
|
||||
CloseHandle ( hImpersonationToken );
|
||||
}
|
||||
if( hToken )
|
||||
{
|
||||
CloseHandle ( hToken );
|
||||
}
|
||||
}
|
||||
|
||||
return fReturn != FALSE;
|
||||
}
|
@ -0,0 +1,660 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef wxAbstractionH
|
||||
#define wxAbstractionH wxAbstractionH
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <apps/Common/Info.h>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "wxIncludePrologue.h"
|
||||
#include <wx/button.h>
|
||||
#include <wx/combobox.h>
|
||||
#include <wx/config.h>
|
||||
#include <wx/dialog.h>
|
||||
#include <wx/dynlib.h>
|
||||
#include <wx/hyperlink.h>
|
||||
#include <wx/listctrl.h>
|
||||
#include <wx/log.h>
|
||||
#include <wx/notebook.h>
|
||||
#include <wx/settings.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/splash.h>
|
||||
#include <wx/socket.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/string.h>
|
||||
#include <wx/textctrl.h>
|
||||
#include <wx/timer.h>
|
||||
#include <wx/window.h>
|
||||
#include "wxIncludeEpilogue.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
struct ConvertedString : wxString
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
#if wxUSE_UNICODE
|
||||
ConvertedString( const char* s ) :
|
||||
wxString( s, wxConvUTF8 ) {}
|
||||
ConvertedString( const std::string& s ) :
|
||||
wxString( s.c_str(), wxConvUTF8 ) {}
|
||||
ConvertedString( const wxString& s ) :
|
||||
# if wxCHECK_VERSION(2,9,0)
|
||||
wxString( s.mb_str(), wxConvUTF8 ) {}
|
||||
# else
|
||||
wxString( s.c_str(), wxConvUTF8 ) {}
|
||||
# endif
|
||||
#else
|
||||
ConvertedString( const char* s ) :
|
||||
wxString( s ) {}
|
||||
ConvertedString( const std::string& s ) :
|
||||
wxString( s.c_str() ) {}
|
||||
ConvertedString( const wxString& s ) :
|
||||
# if wxCHECK_VERSION(2,9,0)
|
||||
wxString( s.mb_str() ) {}
|
||||
# else
|
||||
wxString( s.c_str() ) {}
|
||||
# endif
|
||||
#endif
|
||||
};
|
||||
|
||||
#if ( wxMINOR_VERSION > 6 ) && ( wxMAJOR_VERSION < 3 ) && !WXWIN_COMPATIBILITY_2_6
|
||||
#include <wx/filedlg.h>
|
||||
enum
|
||||
{
|
||||
wxOPEN = wxFD_OPEN,
|
||||
wxSAVE = wxFD_SAVE,
|
||||
wxOVERWRITE_PROMPT = wxFD_OVERWRITE_PROMPT,
|
||||
wxFILE_MUST_EXIST = wxFD_FILE_MUST_EXIST,
|
||||
wxMULTIPLE = wxFD_MULTIPLE,
|
||||
wxCHANGE_DIR = wxFD_CHANGE_DIR
|
||||
};
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
enum TApplicationColors
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
acRedPastel = ( 200 << 16 ) | ( 200 << 8 ) | 255,
|
||||
acYellowPastel = ( 180 << 16 ) | ( 255 << 8 ) | 255,
|
||||
acBluePastel = ( 255 << 16 ) | ( 220 << 8 ) | 200,
|
||||
acDarkBluePastel = ( 255 << 16 ) | ( 100 << 8 ) | 80,
|
||||
acGreenPastel = ( 200 << 16 ) | ( 255 << 8 ) | 200,
|
||||
acGreyPastel = ( 200 << 16 ) | ( 200 << 8 ) | 200,
|
||||
acDarkGrey = ( 100 << 16 ) | ( 100 << 8 ) | 100
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
//================= Implementation FramePositionStorage =======================
|
||||
//=============================================================================
|
||||
//-----------------------------------------------------------------------------
|
||||
class FramePositionStorage
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
wxWindow* m_pWin;
|
||||
public:
|
||||
FramePositionStorage( wxWindow* pWin ) : m_pWin( pWin ) {}
|
||||
void Save( void ) const
|
||||
{
|
||||
Save( m_pWin );
|
||||
}
|
||||
static void Save( wxWindow* pWin, const wxString& windowName = wxT( "MainFrame" ) )
|
||||
{
|
||||
wxConfigBase* pConfig( wxConfigBase::Get() );
|
||||
int Height, Width, XPos, YPos;
|
||||
pWin->GetSize( &Width, &Height );
|
||||
pWin->GetPosition( &XPos, &YPos );
|
||||
// when we e.g. try to write config stuff on a read-only file system the result can
|
||||
// be an annoying message box. Therefore we switch off logging during the storage operation.
|
||||
wxLogNull logSuspendScope;
|
||||
pConfig->Write( wxString::Format( wxT( "/%s/h" ), windowName.c_str() ), Height );
|
||||
pConfig->Write( wxString::Format( wxT( "/%s/w" ), windowName.c_str() ), Width );
|
||||
pConfig->Write( wxString::Format( wxT( "/%s/x" ), windowName.c_str() ), XPos );
|
||||
pConfig->Write( wxString::Format( wxT( "/%s/y" ), windowName.c_str() ), YPos );
|
||||
if( dynamic_cast<wxTopLevelWindow*>( pWin ) )
|
||||
{
|
||||
pConfig->Write( wxString::Format( wxT( "/%s/maximized" ), windowName.c_str() ), dynamic_cast<wxTopLevelWindow*>( pWin )->IsMaximized() );
|
||||
}
|
||||
pConfig->Flush();
|
||||
}
|
||||
static wxRect Load( const wxRect& defaultDimensions, bool& boMaximized, const wxString& windowName = wxT( "MainFrame" ) )
|
||||
{
|
||||
wxConfigBase* pConfig( wxConfigBase::Get() );
|
||||
wxRect rect;
|
||||
rect.height = pConfig->Read( wxString::Format( wxT( "/%s/h" ), windowName.c_str() ), defaultDimensions.height );
|
||||
rect.width = pConfig->Read( wxString::Format( wxT( "/%s/w" ), windowName.c_str() ), defaultDimensions.width );
|
||||
rect.x = pConfig->Read( wxString::Format( wxT( "/%s/x" ), windowName.c_str() ), defaultDimensions.x );
|
||||
rect.y = pConfig->Read( wxString::Format( wxT( "/%s/y" ), windowName.c_str() ), defaultDimensions.y );
|
||||
boMaximized = pConfig->Read( wxString::Format( wxT( "/%s/maximized" ), windowName.c_str() ), 1l ) != 0;
|
||||
int displayWidth = 0;
|
||||
int displayHeight = 0;
|
||||
wxDisplaySize( &displayWidth, &displayHeight );
|
||||
if( ( rect.x >= displayWidth ) || ( ( rect.x + rect.width ) < 0 ) )
|
||||
{
|
||||
rect.x = 0;
|
||||
}
|
||||
if( ( rect.y >= displayHeight ) || ( ( rect.y + rect.height ) < 0 ) )
|
||||
{
|
||||
rect.y = 0;
|
||||
}
|
||||
return rect;
|
||||
}
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
//================= Implementation SplashScreenScope ==========================
|
||||
//=============================================================================
|
||||
//-----------------------------------------------------------------------------
|
||||
class SplashScreenScope
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
wxSplashScreen* pSplash_;
|
||||
wxStopWatch stopWatch_;
|
||||
public:
|
||||
explicit SplashScreenScope( const wxBitmap& bmp, const wxBitmap& icon ) : pSplash_( 0 ), stopWatch_()
|
||||
{
|
||||
pSplash_ = new wxSplashScreen( ( wxSystemSettings::GetScreenType() <= wxSYS_SCREEN_SMALL ) ? icon : bmp, wxSPLASH_CENTRE_ON_SCREEN | wxSPLASH_NO_TIMEOUT, 0, NULL, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER );
|
||||
pSplash_->Update();
|
||||
}
|
||||
virtual ~SplashScreenScope()
|
||||
{
|
||||
const unsigned long startupTime_ms = static_cast<unsigned long>( stopWatch_.Time() );
|
||||
const unsigned long minSplashDisplayTime_ms = 3000;
|
||||
if( startupTime_ms < minSplashDisplayTime_ms )
|
||||
{
|
||||
wxMilliSleep( minSplashDisplayTime_ms - startupTime_ms );
|
||||
}
|
||||
delete pSplash_;
|
||||
}
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
//================= Implementation SocketInitializeScope ======================
|
||||
//=============================================================================
|
||||
//-----------------------------------------------------------------------------
|
||||
class SocketInitializeScope
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
public:
|
||||
explicit SocketInitializeScope()
|
||||
{
|
||||
// This has to be called in order to be able to initialize sockets outside of
|
||||
// the main thread ( http://www.litwindow.com/Knowhow/wxSocket/wxsocket.html )
|
||||
wxSocketBase::Initialize();
|
||||
}
|
||||
~SocketInitializeScope()
|
||||
{
|
||||
// Must apparently be done since we called wxSocketBase::Initialize(),
|
||||
// otherwise memory leaks occur when closing the application.
|
||||
wxSocketBase::Shutdown();
|
||||
}
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
//================= Implementation miscellaneous helper functions =============
|
||||
//=============================================================================
|
||||
//-----------------------------------------------------------------------------
|
||||
inline wxString LoadGenTLProducer( wxDynamicLibrary& lib )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
#ifdef _WIN32
|
||||
const wxString libName( wxT( "mvGenTLProducer.cti" ) );
|
||||
#else
|
||||
const wxString libName( wxT( "libmvGenTLProducer.so" ) );
|
||||
#endif
|
||||
|
||||
const wxString GenTLPathVariable( ( sizeof( void* ) == 8 ) ? wxT( "GENICAM_GENTL64_PATH" ) : wxT( "GENICAM_GENTL32_PATH" ) );
|
||||
#if defined(linux) || defined(__linux) || defined(__linux__)
|
||||
const wxChar PATH_SEPARATOR( wxT( ':' ) );
|
||||
#elif defined(_WIN32) || defined(WIN32) || defined(__WIN32__)
|
||||
const wxChar PATH_SEPARATOR( wxT( ';' ) );
|
||||
#else
|
||||
# error Unsupported target platform
|
||||
#endif
|
||||
wxString GenTLPath;
|
||||
wxArrayString potentialLocations;
|
||||
if( ::wxGetEnv( GenTLPathVariable, &GenTLPath ) )
|
||||
{
|
||||
potentialLocations = wxSplit( GenTLPath, PATH_SEPARATOR );
|
||||
}
|
||||
|
||||
wxString message;
|
||||
// when we e.g. trying to load a shared library that cannot be found the result can
|
||||
// be an annoying message box. Therefore we switch off logging during the load attempts.
|
||||
wxLogNull logSuspendScope;
|
||||
const size_t potentialLocationCount = potentialLocations.Count();
|
||||
for( size_t i = 0; i < potentialLocationCount; i++ )
|
||||
{
|
||||
lib.Load( potentialLocations[i] + wxT( "/" ) + libName, wxDL_VERBATIM );
|
||||
if( lib.IsLoaded() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( !lib.IsLoaded() )
|
||||
{
|
||||
lib.Load( libName, wxDL_VERBATIM );
|
||||
}
|
||||
if( !lib.IsLoaded() )
|
||||
{
|
||||
message = wxString::Format( wxT( "Could not connect to '%s'. Check your installation.\n\n" ), libName.c_str() );
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline void AddSourceInfo( wxWindow* pParent, wxSizer* pParentSizer )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
wxBoxSizer* pSizer = new wxBoxSizer( wxHORIZONTAL );
|
||||
pSizer->Add( new wxStaticText( pParent, wxID_ANY, wxT( "The complete source code belonging to this application can be obtained by contacting " ) ) );
|
||||
pSizer->Add( new wxHyperlinkCtrl( pParent, wxID_ANY, COMPANY_NAME, COMPANY_WEBSITE ) );
|
||||
pParentSizer->Add( pSizer, 0, wxALL | wxALIGN_CENTER, 5 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline void AddSupportInfo( wxWindow* pParent, wxSizer* pParentSizer )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
wxBoxSizer* pSizer = new wxBoxSizer( wxHORIZONTAL );
|
||||
pSizer->Add( new wxStaticText( pParent, wxID_ANY, wxT( "Support contact: " ) ) );
|
||||
pSizer->Add( new wxHyperlinkCtrl( pParent, wxID_ANY, COMPANY_SUPPORT_MAIL, COMPANY_SUPPORT_MAIL ) );
|
||||
pParentSizer->Add( pSizer, 0, wxALL | wxALIGN_CENTER, 5 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline void AddwxWidgetsInfo( wxWindow* pParent, wxSizer* pParentSizer )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
wxBoxSizer* pSizer = new wxBoxSizer( wxHORIZONTAL );
|
||||
pSizer->Add( new wxStaticText( pParent, wxID_ANY, wxT( "This tool has been written using " ) ) );
|
||||
pSizer->Add( new wxHyperlinkCtrl( pParent, wxID_ANY, wxT( "wxWidgets" ), wxT( "http://www.wxwidgets.org" ) ) );
|
||||
pSizer->Add( new wxStaticText( pParent, wxID_ANY, wxString::Format( wxT( " %d.%d.%d." ), wxMAJOR_VERSION, wxMINOR_VERSION, wxRELEASE_NUMBER ) ) );
|
||||
pParentSizer->Add( pSizer, 0, wxALL | wxALIGN_CENTER, 5 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline void AddIconInfo( wxWindow* pParent, wxSizer* pParentSizer )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
wxBoxSizer* pSizer = new wxBoxSizer( wxHORIZONTAL );
|
||||
pSizer->Add( new wxStaticText( pParent, wxID_ANY, wxT( "This tool uses modified icons downloaded from here " ) ) );
|
||||
pSizer->Add( new wxHyperlinkCtrl( pParent, wxID_ANY, wxT( "icons8" ), wxT( "https://icons8.com/" ) ) );
|
||||
pSizer->Add( new wxStaticText( pParent, wxID_ANY, wxT( " and here " ) ) );
|
||||
pSizer->Add( new wxHyperlinkCtrl( pParent, wxID_ANY, wxT( "Freepik" ), wxT( "http://www.freepik.com" ) ) );
|
||||
pSizer->Add( new wxStaticText( pParent, wxID_ANY, wxT( ". The " ) ) );
|
||||
pSizer->Add( new wxHyperlinkCtrl( pParent, wxID_ANY, wxT( "Material Design" ), wxT( "https://material.io/resources/icons/?style=outline" ) ) );
|
||||
pSizer->Add( new wxStaticText( pParent, wxID_ANY, wxT( " icons are published under " ) ) );
|
||||
pSizer->Add( new wxHyperlinkCtrl( pParent, wxID_ANY, wxT( "Apache 2.0 license." ), wxT( "https://www.apache.org/licenses/LICENSE-2.0.html" ) ) );
|
||||
pParentSizer->Add( pSizer, 0, wxALL | wxALIGN_CENTER, 5 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline void AddListControlToAboutNotebook( wxNotebook* pNotebook, const wxString& pageTitle, bool boSelectPage, const wxString& col0, const wxString& col1, const std::vector<std::pair<wxString, wxString> >& v )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
wxListCtrl* pListCtrl = new wxListCtrl( pNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxLC_SINGLE_SEL | wxBORDER_NONE );
|
||||
pListCtrl->InsertColumn( 0, col0 );
|
||||
pListCtrl->InsertColumn( 1, col1 );
|
||||
const unsigned long cnt = static_cast<unsigned long>( v.size() );
|
||||
for( unsigned long i = 0; i < cnt; i++ )
|
||||
{
|
||||
long index = pListCtrl->InsertItem( i, v[i].first, i );
|
||||
pListCtrl->SetItem( index, 1, v[i].second );
|
||||
}
|
||||
for( unsigned int i = 0; i < 2; i++ )
|
||||
{
|
||||
pListCtrl->SetColumnWidth( i, wxLIST_AUTOSIZE );
|
||||
}
|
||||
pNotebook->AddPage( pListCtrl, pageTitle, boSelectPage );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline void AppendPathSeparatorIfNeeded( wxString& path )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( !path.EndsWith( wxT( "/" ) ) && !path.EndsWith( wxT( "\\" ) ) )
|
||||
{
|
||||
path.append( wxT( "/" ) );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline void WriteToTextCtrl( wxTextCtrl* pTextCtrl, const wxString& msg, const wxTextAttr& style = wxTextAttr( *wxBLACK ) )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( pTextCtrl )
|
||||
{
|
||||
// If you want the control to show the last line of text at the bottom, you can add "ScrollLines(1)"
|
||||
// right after the AppendText call. AppendText will ensure the new line is visible, and ScrollLines
|
||||
// will ensure the scroll bar is at the real end of the range, not further.
|
||||
long posBefore = pTextCtrl->GetLastPosition();
|
||||
pTextCtrl->AppendText( msg );
|
||||
long posAfter = pTextCtrl->GetLastPosition();
|
||||
pTextCtrl->SetStyle( posBefore, posAfter, style );
|
||||
pTextCtrl->ScrollLines( 1 );
|
||||
pTextCtrl->ShowPosition( pTextCtrl->GetLastPosition() ); // ensure that this position is really visible
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
struct AboutDialogInformation
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
wxIcon icon_;
|
||||
wxWindow* pParent_;
|
||||
wxString applicationName_;
|
||||
wxString briefDescription_;
|
||||
unsigned int yearOfInitialRelease_;
|
||||
std::vector<std::pair<wxString, wxTextAttr> > usageHints_;
|
||||
std::vector<std::pair<wxString, wxString> > keyboardShortcuts_;
|
||||
std::vector<std::pair<wxString, wxString> > availableCommandLineOptions_;
|
||||
bool boAddIconInfo_;
|
||||
bool boAddExpatInfo_;
|
||||
bool boAddFFmpegInfo_;
|
||||
explicit AboutDialogInformation( const wxIcon& icon, wxWindow* pParent = 0 ) : icon_( icon ), pParent_( pParent ), applicationName_(),
|
||||
briefDescription_(), yearOfInitialRelease_( 2005 ), usageHints_(), keyboardShortcuts_(),
|
||||
availableCommandLineOptions_(), boAddIconInfo_( false ), boAddExpatInfo_( false ), boAddFFmpegInfo_( false ) {}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline void DisplayCommandLineProcessingInformation( wxTextCtrl* pTextCtrl, const wxString& processedCommandLineParameters, const wxString& parserErrors, const wxTextAttr& style )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
WriteToTextCtrl( pTextCtrl, wxT( "\n" ) );
|
||||
WriteToTextCtrl( pTextCtrl, wxT( "Press 'F1' for help.\n" ), style );
|
||||
WriteToTextCtrl( pTextCtrl, wxT( "\n" ) );
|
||||
const wxString none( wxT( "none" ) );
|
||||
WriteToTextCtrl( pTextCtrl, wxString::Format( wxT( "Processed command line parameters: %s\n" ), ( processedCommandLineParameters.length() > 0 ) ? processedCommandLineParameters.c_str() : none.c_str() ), style );
|
||||
WriteToTextCtrl( pTextCtrl, wxT( "\n" ) );
|
||||
if( !parserErrors.IsEmpty() )
|
||||
{
|
||||
WriteToTextCtrl( pTextCtrl, parserErrors, wxTextAttr( *wxRED ) );
|
||||
WriteToTextCtrl( pTextCtrl, wxT( "\n" ) );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline void DisplayCommonAboutDialog( const AboutDialogInformation& info )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
wxBoxSizer* pTopDownSizer;
|
||||
wxDialog dlg( info.pParent_, wxID_ANY, wxString( wxString::Format( wxT( "About %s" ), info.applicationName_.c_str() ) ), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMAXIMIZE_BOX | wxMINIMIZE_BOX );
|
||||
dlg.SetIcon( info.icon_ );
|
||||
pTopDownSizer = new wxBoxSizer( wxVERTICAL );
|
||||
wxStaticText* pText = new wxStaticText( &dlg, wxID_ANY, info.briefDescription_ );
|
||||
pTopDownSizer->Add( pText, 0, wxALL | wxALIGN_CENTER, 5 );
|
||||
pText = new wxStaticText( &dlg, wxID_ANY, wxString::Format( wxT( "(C) %u - %s by %s" ), info.yearOfInitialRelease_, CURRENT_YEAR, COMPANY_NAME ) );
|
||||
pTopDownSizer->Add( pText, 0, wxALL | wxALIGN_CENTER, 5 );
|
||||
pText = new wxStaticText( &dlg, wxID_ANY, wxString::Format( wxT( "Version %s" ), VERSION_STRING ) );
|
||||
pTopDownSizer->Add( pText, 0, wxALL | wxALIGN_CENTER, 5 );
|
||||
AddSupportInfo( &dlg, pTopDownSizer );
|
||||
AddwxWidgetsInfo( &dlg, pTopDownSizer );
|
||||
if( info.boAddIconInfo_ )
|
||||
{
|
||||
AddIconInfo( &dlg, pTopDownSizer );
|
||||
}
|
||||
if( info.boAddExpatInfo_ )
|
||||
{
|
||||
pText = new wxStaticText( &dlg, wxID_ANY, wxT( "The expat wrapper class used internally has been written by Descartes Systems Sciences, Inc." ) );
|
||||
pTopDownSizer->Add( pText, 0, wxALL | wxALIGN_CENTER, 5 );
|
||||
}
|
||||
if( info.boAddFFmpegInfo_ )
|
||||
{
|
||||
wxBoxSizer* pSizer = new wxBoxSizer( wxHORIZONTAL );
|
||||
pSizer->Add( new wxStaticText( &dlg, wxID_ANY, wxT( "The video recording functionality of this application was implemented using libraries from the " ) ) );
|
||||
pSizer->Add( new wxHyperlinkCtrl( &dlg, wxID_ANY, wxT( "FFmpeg" ), wxT( "https://www.ffmpeg.org/" ) ) );
|
||||
pSizer->Add( new wxStaticText( &dlg, wxID_ANY, wxT( " project under the LGPLv2.1. These must be installed separately" ) ) );
|
||||
pTopDownSizer->Add( pSizer, 0, wxALL | wxALIGN_CENTER, 5 );
|
||||
}
|
||||
AddSourceInfo( &dlg, pTopDownSizer );
|
||||
wxNotebook* pNotebook = new wxNotebook( &dlg, wxID_ANY, wxDefaultPosition, wxDefaultSize );
|
||||
wxTextCtrl* pUsageHints = new wxTextCtrl( pNotebook, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxBORDER_NONE | wxTE_RICH | wxTE_READONLY );
|
||||
pNotebook->AddPage( pUsageHints, wxT( "Usage Hints" ), true );
|
||||
std::vector<std::pair<wxTextAttr, wxString> >::size_type usageHintStringCount = info.usageHints_.size();
|
||||
for( std::vector<std::pair<wxString, wxTextAttr> >::size_type i = 0; i < usageHintStringCount; i++ )
|
||||
{
|
||||
WriteToTextCtrl( pUsageHints, info.usageHints_[i].first, info.usageHints_[i].second );
|
||||
}
|
||||
pUsageHints->ScrollLines( -( 256 * 256 ) ); // make sure the text control always shows the beginning of the help text
|
||||
if( !info.keyboardShortcuts_.empty() )
|
||||
{
|
||||
AddListControlToAboutNotebook( pNotebook, wxT( "Keyboard Shortcuts" ), false, wxT( "Shortcut" ), wxT( "Command" ), info.keyboardShortcuts_ );
|
||||
}
|
||||
if( !info.availableCommandLineOptions_.empty() )
|
||||
{
|
||||
AddListControlToAboutNotebook( pNotebook, wxT( "Available Command Line Options" ), false, wxT( "Command" ), wxT( "Description" ), info.availableCommandLineOptions_ );
|
||||
}
|
||||
pTopDownSizer->AddSpacer( 10 );
|
||||
pTopDownSizer->Add( pNotebook, wxSizerFlags( 5 ).Expand() );
|
||||
pTopDownSizer->AddSpacer( 10 );
|
||||
wxButton* pBtnOK = new wxButton( &dlg, wxID_OK, wxT( "OK" ) );
|
||||
pBtnOK->SetDefault();
|
||||
pTopDownSizer->Add( pBtnOK, 0, wxALL | wxALIGN_RIGHT, 15 );
|
||||
dlg.SetSizer( pTopDownSizer );
|
||||
dlg.SetSizeHints( 720, 500 );
|
||||
dlg.SetSize( -1, -1, 800, 500 );
|
||||
dlg.ShowModal();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline wxTextAttr GetCommonTextStyle( const bool boBold, const bool boUnderlined, wxTextCtrl*
|
||||
#if wxCHECK_VERSION(2, 9, 5)
|
||||
#else
|
||||
pParent
|
||||
#endif // #if wxCHECK_VERSION(2, 9, 5)
|
||||
)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
wxTextAttr theStyle;
|
||||
#if wxCHECK_VERSION(2, 9, 5)
|
||||
wxFontInfo fontInfo( 10 );
|
||||
if( boBold )
|
||||
{
|
||||
fontInfo.Bold();
|
||||
}
|
||||
if( boUnderlined )
|
||||
{
|
||||
fontInfo.Underlined();
|
||||
}
|
||||
wxFont theFont( fontInfo );
|
||||
#else
|
||||
pParent->GetStyle( pParent->GetLastPosition(), theStyle );
|
||||
wxFont theFont( theStyle.GetFont() );
|
||||
if( boBold )
|
||||
{
|
||||
theFont.SetWeight( wxFONTWEIGHT_BOLD );
|
||||
}
|
||||
theFont.SetPointSize( 10 );
|
||||
if( boUnderlined )
|
||||
{
|
||||
theFont.SetUnderlined( true );
|
||||
}
|
||||
#endif // #if wxCHECK_VERSION(2, 9, 5)
|
||||
theStyle.SetFont( theFont );
|
||||
return theStyle;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline wxTextAttr GetBoldStyle( wxTextCtrl* pParent )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return GetCommonTextStyle( true, false, pParent );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline wxTextAttr GetBoldUnderlinedStyle( wxTextCtrl* pParent )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return GetCommonTextStyle( true, true, pParent );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline wxTextAttr GetDefaultStyle( wxTextCtrl* pParent )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return GetCommonTextStyle( false, false, pParent );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline wxTextAttr GetUnderlinedStyle( wxTextCtrl* pParent )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return GetCommonTextStyle( false, true, pParent );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool IsListOfChoicesEmpty( wxComboBox* pCB )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
#if wxCHECK_VERSION(2, 9, 3)
|
||||
return pCB->IsListEmpty();
|
||||
#else
|
||||
return pCB->IsEmpty();
|
||||
#endif // #if wxCHECK_VERSION(2, 9, 3)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline void StopTimer( wxTimer& timer )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( timer.IsRunning() )
|
||||
{
|
||||
timer.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//===================== Implementation Version helper functions ===============
|
||||
//=============================================================================
|
||||
//-----------------------------------------------------------------------------
|
||||
struct Version
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
long major_;
|
||||
long minor_;
|
||||
long subMinor_;
|
||||
long release_;
|
||||
explicit Version() : major_( -1 ), minor_( -1 ), subMinor_( -1 ), release_( 0 ) {}
|
||||
explicit Version( long ma, long mi, long smi, long re ) : major_( ma ), minor_( mi ), subMinor_( smi ), release_( re ) {}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool operator<( const Version& a, const Version& b )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( a.major_ < b.major_ )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if( a.major_ == b.major_ )
|
||||
{
|
||||
if( a.minor_ < b.minor_ )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if( a.minor_ == b.minor_ )
|
||||
{
|
||||
if( a.subMinor_ < b.subMinor_ )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if( a.subMinor_ == b.subMinor_ )
|
||||
{
|
||||
if( a.release_ < b.release_ )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool operator==( const Version& a, const Version& b )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return ( ( a.major_ == b.major_ ) && ( a.minor_ == b.minor_ ) && ( a.subMinor_ == b.subMinor_ ) && ( a.release_ == b.release_ ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool operator!=( const Version& a, const Version& b )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return ( ( a.major_ != b.major_ ) || ( a.minor_ != b.minor_ ) || ( a.subMinor_ != b.subMinor_ ) || ( a.release_ != b.release_ ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool operator>( const Version& a, const Version& b )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return ( !( a < b ) && !( a == b ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool operator>=( const Version& a, const Version& b )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return ( a > b ) || ( a == b );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool operator<=( const Version& a, const Version& b )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return ( a < b ) || ( a == b );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool GetNextVersionNumber( wxString& str, long& number )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
wxString numberString = str.BeforeFirst( wxT( '.' ) );
|
||||
str = str.AfterFirst( wxT( '.' ) );
|
||||
return numberString.ToLong( &number );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline Version VersionFromString( const wxString& versionAsString )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
Version version;
|
||||
wxString tmp( versionAsString );
|
||||
GetNextVersionNumber( tmp, version.major_ );
|
||||
if( !tmp.empty() )
|
||||
{
|
||||
GetNextVersionNumber( tmp, version.minor_ );
|
||||
if( !tmp.empty() )
|
||||
{
|
||||
GetNextVersionNumber( tmp, version.subMinor_ );
|
||||
if( !tmp.empty() )
|
||||
{
|
||||
GetNextVersionNumber( tmp, version.release_ );
|
||||
}
|
||||
}
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool IsVersionWithinRange( const Version& version, const Version& minVersion, const Version& maxVersion )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return ( version >= minVersion ) && ( version <= maxVersion );
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//============= Implementation IP Address conversion functions ================
|
||||
//=============================================================================
|
||||
//-----------------------------------------------------------------------------
|
||||
inline std::string GetIPv4AddressAsString( unsigned int ip )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
std::ostringstream output;
|
||||
output << ( ( ip >> 24 ) & 0xFF ) << "." << ( ( ip >> 16 ) & 0xFF ) << "." << ( ( ip >> 8 ) & 0xFF ) << "." << ( ip & 0xFF );
|
||||
return output.str();
|
||||
}
|
||||
|
||||
#endif // wxAbstractionH
|
@ -0,0 +1,5 @@
|
||||
#if defined(__clang__)
|
||||
# pragma clang diagnostic pop
|
||||
#elif defined(_MSC_VER) && (_MSC_VER >= 1400) // is at least VC 2005 compiler?
|
||||
# pragma warning( pop )
|
||||
#endif
|
@ -0,0 +1,10 @@
|
||||
#if defined(__clang__)
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
# pragma clang diagnostic ignored "-Wunused-local-typedef"
|
||||
#elif defined(_MSC_VER) && (_MSC_VER >= 1400) // is at least VC 2005 compiler?
|
||||
# pragma warning( push )
|
||||
# pragma warning( disable : 4127 ) // 'conditional expression is constant'
|
||||
# pragma warning( disable : 4512 ) // 'class XYZ': assignment operator could not be generated'
|
||||
# pragma warning( disable : 4996 ) // ''function XYZ': was declared deprecated'
|
||||
#endif
|
@ -0,0 +1,9 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef wxIncluderH
|
||||
#define wxIncluderH wxIncluderH
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <apps/Common/wxIncludePrologue.h>
|
||||
#include "wx/wx.h"
|
||||
#include <apps/Common/wxIncludeEpilogue.h>
|
||||
|
||||
#endif // wxIncluderH
|
@ -0,0 +1,360 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// (C) Copyright 2005 - 2021 by MATRIX VISION GmbH
|
||||
//
|
||||
// This software is provided by MATRIX VISION GmbH "as is"
|
||||
// and any express or implied warranties, including, but not limited to, the
|
||||
// implied warranties of merchantability and fitness for a particular purpose
|
||||
// are disclaimed.
|
||||
//
|
||||
// In no event shall MATRIX VISION GmbH be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused and
|
||||
// on any theory of liability, whether in contract, strict liability, or tort
|
||||
// (including negligence or otherwise) arising in any way out of the use of
|
||||
// this software, even if advised of the possibility of such damage.
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef STLHelperH
|
||||
#define STLHelperH STLHelperH
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <cstdio>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
//=============================================================================
|
||||
//==================== std::pair related stuff ================================
|
||||
//=============================================================================
|
||||
//-----------------------------------------------------------------------------
|
||||
template<class _Ty1, class _Ty2>
|
||||
const _Ty1& GetFirst( const std::pair<_Ty1, _Ty2>& data )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return data.first;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template<class _Ty1, class _Ty2>
|
||||
const _Ty2& GetSecond( const std::pair<_Ty1, _Ty2>& data )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return data.second;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template<class _Ty1, class _Ty2>
|
||||
void DeleteFirst( std::pair<_Ty1, _Ty2>& data )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
delete data.first;
|
||||
data.first = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template<class _Ty1, class _Ty2>
|
||||
void DeleteSecond( std::pair<_Ty1, _Ty2>& data )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
delete data.second;
|
||||
data.second = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template<class _Ty1, class _Ty2>
|
||||
class ContainsFirst : public std::unary_function<std::pair<_Ty1, _Ty2>, bool>
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
std::map<_Ty1, _Ty2> m_;
|
||||
public:
|
||||
explicit ContainsFirst( const std::map<_Ty1, _Ty2>& m ) : m_( m ) {}
|
||||
bool operator()( const std::pair<_Ty1, _Ty2>& x )
|
||||
{
|
||||
return m_.find( x.first ) != m_.end();
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template<class _Ty1, class _Ty2>
|
||||
class FirstMatches : public std::unary_function<std::pair<_Ty1, _Ty2>, bool>
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
std::pair<_Ty1, _Ty2> value_;
|
||||
FirstMatches<_Ty1, _Ty2>& operator=( const FirstMatches<_Ty1, _Ty2>& ); // do not allow assignments
|
||||
public:
|
||||
explicit FirstMatches( const std::pair<_Ty1, _Ty2>& val ) : value_( val ) {}
|
||||
bool operator()( const std::pair<_Ty1, _Ty2>& x )
|
||||
{
|
||||
return x.first == value_.first;
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template<class _Ty1, class _Ty2>
|
||||
class SecondMatches : public std::unary_function<std::pair<_Ty1, _Ty2>, bool>
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
std::pair<_Ty1, _Ty2> value_;
|
||||
SecondMatches<_Ty1, _Ty2>& operator=( const SecondMatches<_Ty1, _Ty2>& ); // do not allow assignments
|
||||
public:
|
||||
explicit SecondMatches( const std::pair<_Ty1, _Ty2>& val ) : value_( val ) {}
|
||||
bool operator()( const std::pair<_Ty1, _Ty2>& x )
|
||||
{
|
||||
return x.second == value_.second;
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename _Ty1, typename _Ty2>
|
||||
bool SecondSmaller( const std::pair<_Ty1, _Ty2>& a, const std::pair<_Ty1, _Ty2>& b )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( a.second < b.second )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if( a.second > b.second )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return ( a.first < b.first );
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//==================== various ================================================
|
||||
//=============================================================================
|
||||
//-----------------------------------------------------------------------------
|
||||
template<class _Ty>
|
||||
void DeleteElement( _Ty& data )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
delete data;
|
||||
data = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template<class _Ty>
|
||||
void DeleteArrayElement( _Ty& data )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
delete [] data;
|
||||
data = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \brief Proxy reference for ObjectDeleter copying.
|
||||
template<class _Ty>
|
||||
struct ObjectDeleterReference
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
// construct from generic pointer to ObjectDeleter pointer
|
||||
explicit ObjectDeleterReference( _Ty* rhs ) : pReference_( rhs ) {}
|
||||
|
||||
_Ty* pReference_; // generic pointer to ObjectDeleter pointer
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \brief Simple wrapper class to make sure an object is deleted at the end of the scope
|
||||
/**
|
||||
* This of course could also be done using std::auto_ptr but as this template has been
|
||||
* declared deprecated it causes new compilers to spit out warnings/failures.
|
||||
*
|
||||
* The nice way of doing this would be by the use of std::unique_ptr these days but then
|
||||
* the client code would force people to have a C++11 or greater compliant compiler...
|
||||
*/
|
||||
template<class _Ty>
|
||||
class ObjectDeleter
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
_Ty* pObject_;
|
||||
public:
|
||||
explicit ObjectDeleter( _Ty* pObject = 0 ) : pObject_( pObject ) {}
|
||||
/// \brief Pass ownership to the new object.
|
||||
ObjectDeleter( ObjectDeleter<_Ty>& rhs ) : pObject_( rhs.release() ) {}
|
||||
~ObjectDeleter()
|
||||
{
|
||||
DeleteElement( pObject_ );
|
||||
}
|
||||
/// \brief Pass ownership. Old buffer on the left hand side object is
|
||||
/// freed, the lhs object takes ownership of the pointer of the rhs object.
|
||||
ObjectDeleter<_Ty>& operator=( ObjectDeleter<_Ty>& rhs )
|
||||
{
|
||||
if( this != &rhs )
|
||||
{
|
||||
DeleteElement( pObject_ );
|
||||
pObject_ = rhs.release();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
template<class _Other>
|
||||
operator ObjectDeleterReference<_Other>()
|
||||
{
|
||||
// convert to compatible ObjectDeleterReference
|
||||
_Other* p = pObject_; // test implicit conversion
|
||||
ObjectDeleterReference<_Other> reference( p );
|
||||
pObject_ = 0; // pass ownership to ObjectDeleterReference
|
||||
return ( reference );
|
||||
}
|
||||
ObjectDeleter<_Ty>& operator=( ObjectDeleterReference<_Ty> rhs )
|
||||
{
|
||||
// assign compatible rhs.pReference_ (assume pointer)
|
||||
_Ty* p = rhs.pReference_;
|
||||
rhs.pReference_ = 0;
|
||||
reset( p );
|
||||
return ( *this );
|
||||
}
|
||||
operator _Ty* ()
|
||||
{
|
||||
return pObject_;
|
||||
}
|
||||
_Ty* operator->()
|
||||
{
|
||||
return pObject_;
|
||||
}
|
||||
_Ty* get( void )
|
||||
{
|
||||
return pObject_;
|
||||
}
|
||||
const _Ty* get( void ) const
|
||||
{
|
||||
return pObject_;
|
||||
}
|
||||
_Ty* release( void )
|
||||
{
|
||||
_Ty* p = pObject_;
|
||||
pObject_ = 0;
|
||||
return p;
|
||||
}
|
||||
void reset( _Ty* pObject = 0 )
|
||||
{
|
||||
if( pObject_ != pObject )
|
||||
{
|
||||
DeleteElement( pObject_ );
|
||||
pObject_ = pObject;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// This could in theory be accomplished with a call to the for_each template:
|
||||
///
|
||||
/// for_each( s.begin(), s.end(), ptr_fun(DeleteElement<_Ty*>) );
|
||||
///
|
||||
/// But some ports of the STL always return const_iterators for sets (e.g. gcc 4.1.2)
|
||||
template<class _Ty>
|
||||
void ClearSetWithHeapAllocatedKeys( std::set<_Ty>& s )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
typename std::set<_Ty>::iterator it = s.begin();
|
||||
typename std::set<_Ty>::iterator itEnd = s.end();
|
||||
while( it != itEnd )
|
||||
{
|
||||
delete *it;
|
||||
++it;
|
||||
}
|
||||
s.clear();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \brief Assigns a new value to a variable when this objects goes out of scope.
|
||||
///
|
||||
/// Can be useful if a variable must be set to a defined value at the end of a
|
||||
/// code block that might rise an exception.
|
||||
template<class T>
|
||||
class VarScopeMod
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
T& var_;
|
||||
T valAtEndOfScope_;
|
||||
VarScopeMod( const VarScopeMod& ); // do not allow copy constructor
|
||||
VarScopeMod& operator=( const VarScopeMod& ); // do not allow assignments
|
||||
public:
|
||||
explicit VarScopeMod( T& var, T valAtEndOfScope ) : var_( var ), valAtEndOfScope_( valAtEndOfScope ) {}
|
||||
explicit VarScopeMod( T& var, T valWithinScope, T valAtEndOfScope ) : var_( var ), valAtEndOfScope_( valAtEndOfScope )
|
||||
{
|
||||
var = valWithinScope;
|
||||
}
|
||||
~VarScopeMod()
|
||||
{
|
||||
var_ = valAtEndOfScope_;
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template<class T>
|
||||
void removeDuplicates( T& container )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
std::sort( container.begin(), container.end() );
|
||||
typename T::iterator it = std::unique( container.begin(), container.end() );
|
||||
container.erase( it, container.end() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template<class _Elem>
|
||||
_Elem mv_tolower( _Elem c )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return static_cast<_Elem>( tolower( c ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template<class _Elem, class _Traits, class _Ax>
|
||||
void makeLowerCase(
|
||||
/// The string to convert
|
||||
std::basic_string<_Elem, _Traits, _Ax>& s )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
std::transform( s.begin(), s.end(), s.begin(), std::ptr_fun<_Elem, _Elem>( mv_tolower ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template<class _Elem, class _Traits, class _Ax>
|
||||
std::basic_string<_Elem, _Traits, _Ax> makeLowerCase(
|
||||
/// The string to convert
|
||||
const std::basic_string<_Elem, _Traits, _Ax>& s )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
std::basic_string<_Elem, _Traits, _Ax> lc( s );
|
||||
std::transform( lc.begin(), lc.end(), lc.begin(), std::ptr_fun<_Elem, _Elem>( mv_tolower ) );
|
||||
return lc;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template<class _Elem>
|
||||
_Elem mv_toupper( _Elem c )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return static_cast<_Elem>( toupper( c ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template<class _Elem, class _Traits, class _Ax>
|
||||
void makeUpperCase(
|
||||
/// The string to convert
|
||||
std::basic_string<_Elem, _Traits, _Ax>& s )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
std::transform( s.begin(), s.end(), s.begin(), std::ptr_fun<_Elem, _Elem>( mv_toupper ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template<class _Elem, class _Traits, class _Ax>
|
||||
std::basic_string<_Elem, _Traits, _Ax> makeUpperCase(
|
||||
/// The string to convert
|
||||
const std::basic_string<_Elem, _Traits, _Ax>& s )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
std::basic_string<_Elem, _Traits, _Ax> uc( s );
|
||||
std::transform( uc.begin(), uc.end(), uc.begin(), std::ptr_fun<_Elem, _Elem>( mv_toupper ) );
|
||||
return uc;
|
||||
}
|
||||
|
||||
#endif // STLHelperH
|
@ -0,0 +1,105 @@
|
||||
// This file will be included from the resource files of the individual libraries belonging to
|
||||
// the current release version of the mvIMPACT Acquire driver packages
|
||||
|
||||
|
||||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 2,43,0,3180
|
||||
PRODUCTVERSION 2,43,0,3180
|
||||
FILEFLAGSMASK 0x17L
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x4L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "080904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "MATRIX VISION GmbH"
|
||||
VALUE "FileDescription", FILE_DESCRIPTION
|
||||
VALUE "FileVersion", "2, 43, 0, 3180"
|
||||
VALUE "InternalName", INTERNAL_NAME
|
||||
VALUE "LegalCopyright", "© 2005 - 2021 MATRIX VISION GmbH, Germany"
|
||||
VALUE "OriginalFilename", ORIGINAL_FILENAME
|
||||
VALUE "ProductName", PRODUCT_NAME
|
||||
VALUE "ProductVersion", "2, 43, 0, 3180"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x809, 1200
|
||||
END
|
||||
END
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
@ -0,0 +1,116 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// (C) Copyright 2005 - 2021 by MATRIX VISION GmbH
|
||||
//
|
||||
// This software is provided by MATRIX VISION GmbH "as is"
|
||||
// and any express or implied warranties, including, but not limited to, the
|
||||
// implied warranties of merchantability and fitness for a particular purpose
|
||||
// are disclaimed.
|
||||
//
|
||||
// In no event shall MATRIX VISION GmbH be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused and
|
||||
// on any theory of liability, whether in contract, strict liability, or tort
|
||||
// (including negligence or otherwise) arising in any way out of the use of
|
||||
// this software, even if advised of the possibility of such damage.
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef auto_array_ptrH
|
||||
#define auto_array_ptrH auto_array_ptrH
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \brief A automatically managed buffer type to handle subscriptable data.
|
||||
template<class T>
|
||||
class auto_array_ptr
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
size_t m_cnt;
|
||||
T* m_pBuf;
|
||||
public:
|
||||
auto_array_ptr( size_t initialSize = 0 ) : m_cnt( initialSize ), m_pBuf( 0 )
|
||||
{
|
||||
if( initialSize > 0 )
|
||||
{
|
||||
m_pBuf = new T[initialSize];
|
||||
}
|
||||
}
|
||||
/// \brief Pass ownership to the new object.
|
||||
auto_array_ptr( auto_array_ptr& rhs ) : m_cnt( rhs.m_cnt ), m_pBuf( rhs.release() ) {}
|
||||
/// \brief Pass ownership to the new object.
|
||||
///
|
||||
/// Do NOT delete the original T*. This is done by this class now.
|
||||
auto_array_ptr( T* pBuf, size_t cnt ) : m_cnt( cnt ), m_pBuf( pBuf ) {}
|
||||
~auto_array_ptr()
|
||||
{
|
||||
delete [] m_pBuf;
|
||||
}
|
||||
// functions
|
||||
operator T* ()
|
||||
{
|
||||
return m_pBuf;
|
||||
}
|
||||
/// \brief Pass ownership. Old buffer on the left hand side object is
|
||||
/// freed, the lhs object takes ownership of the buffer of the rhs object.
|
||||
auto_array_ptr& operator=( auto_array_ptr& rhs )
|
||||
{
|
||||
if( this != &rhs )
|
||||
{
|
||||
delete [] m_pBuf;
|
||||
m_cnt = rhs.m_cnt;
|
||||
m_pBuf = rhs.release();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
/// \brief If the new size differs from the current one free old buffer, allocate new buffer.
|
||||
void realloc( size_t newSize )
|
||||
{
|
||||
if( newSize != m_cnt )
|
||||
{
|
||||
delete [] m_pBuf;
|
||||
m_pBuf = ( newSize > 0 ) ? new T[newSize] : 0;
|
||||
m_cnt = newSize;
|
||||
}
|
||||
}
|
||||
/// \brief Increases the buffer size if necessary and keeps the old data.
|
||||
void grow( size_t newSize )
|
||||
{
|
||||
if( newSize > m_cnt )
|
||||
{
|
||||
T* p = new T[newSize];
|
||||
if( m_pBuf && ( m_cnt > 0 ) )
|
||||
{
|
||||
memcpy( p, m_pBuf, m_cnt );
|
||||
delete [] m_pBuf;
|
||||
}
|
||||
m_pBuf = p;
|
||||
m_cnt = newSize;
|
||||
}
|
||||
}
|
||||
/// \brief Release ownership, return pointer to buffer.
|
||||
T* release( void )
|
||||
{
|
||||
T* p = m_pBuf;
|
||||
m_pBuf = 0;
|
||||
m_cnt = 0;
|
||||
return p;
|
||||
}
|
||||
/// \brief Return pointer to buffer.
|
||||
T* get( void )
|
||||
{
|
||||
return m_pBuf;
|
||||
}
|
||||
/// \brief Return const pointer to buffer.
|
||||
const T* get( void ) const
|
||||
{
|
||||
return m_pBuf;
|
||||
}
|
||||
/// \brief Return element count.
|
||||
size_t parCnt( void ) const
|
||||
{
|
||||
return m_cnt;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // auto_array_ptr
|
@ -0,0 +1,63 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// (C) Copyright 2005 - 2021 by MATRIX VISION GmbH
|
||||
//
|
||||
// This software is provided by MATRIX VISION GmbH "as is"
|
||||
// and any express or implied warranties, including, but not limited to, the
|
||||
// implied warranties of merchantability and fitness for a particular purpose
|
||||
// are disclaimed.
|
||||
//
|
||||
// In no event shall MATRIX VISION GmbH be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused and
|
||||
// on any theory of liability, whether in contract, strict liability, or tort
|
||||
// (including negligence or otherwise) arising in any way out of the use of
|
||||
// this software, even if advised of the possibility of such damage.
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef mvstdioH
|
||||
#define mvstdioH mvstdioH
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#if defined(_MSC_VER)
|
||||
# include <share.h>
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \brief Version that mimics the C11 \c fopen_s function.
|
||||
/**
|
||||
* See \c fopen_s of your runtime implementation for documentation!
|
||||
*/
|
||||
inline int mv_fopen_s( FILE** ppFile, const char* pName, const char* pMode )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400) // is at least VC 2005 compiler?
|
||||
// The M$ version of fopen_s does not support sharing thus parallel access to the same file...
|
||||
// As this is needed by mvIMPACT Acquire e.g. when writing log files from multiple processes into
|
||||
// a common file we have to use the '_fsopen' function with '_SH_DENYNO' here to get
|
||||
// what we want, which is parallel access AND no compiler warnings
|
||||
*ppFile = _fsopen( pName, pMode, _SH_DENYNO );
|
||||
return errno;
|
||||
#elif defined (__STDC_LIB_EXT1__)
|
||||
return fopen_s( ppFile, pName, pMode );
|
||||
#else
|
||||
*ppFile = fopen( pName, pMode );
|
||||
return errno;
|
||||
#endif // #if (defined(_MSC_VER) && (_MSC_VER >= 1400)) || defined (__STDC_LIB_EXT1__) // is at least VC 2005 compiler OR implementation supports CRT extensions?
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \brief Version that mimics the traditional \c fopen function.
|
||||
/**
|
||||
* See \c fopen of your runtime implementation for documentation!
|
||||
*/
|
||||
inline FILE* mv_fopen_s( const char* pName, const char* pMode )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
FILE* pFile = 0;
|
||||
mv_fopen_s( &pFile, pName, pMode );
|
||||
return pFile;
|
||||
}
|
||||
|
||||
#endif // mvstdioH
|
@ -0,0 +1,105 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// (C) Copyright 2005 - 2021 by MATRIX VISION GmbH
|
||||
//
|
||||
// This software is provided by MATRIX VISION GmbH "as is"
|
||||
// and any express or implied warranties, including, but not limited to, the
|
||||
// implied warranties of merchantability and fitness for a particular purpose
|
||||
// are disclaimed.
|
||||
//
|
||||
// In no event shall MATRIX VISION GmbH be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused and
|
||||
// on any theory of liability, whether in contract, strict liability, or tort
|
||||
// (including negligence or otherwise) arising in any way out of the use of
|
||||
// this software, even if advised of the possibility of such damage.
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef mvstringH
|
||||
#define mvstringH mvstringH
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \brief Version that mimics the C11 \c strncpy_s function.
|
||||
/**
|
||||
* See \c strncpy_s of your runtime implementation for documentation!
|
||||
*/
|
||||
inline int mv_strncpy_s( char* pDst, const char* pSrc, size_t bufSize )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
#if (defined(_MSC_VER) && (_MSC_VER >= 1400)) // is at least VC 2005 compiler?
|
||||
// '_TRUNCATE' is a Microsoft extension!
|
||||
return strncpy_s( pDst, bufSize, pSrc, _TRUNCATE );
|
||||
#elif defined (__STDC_LIB_EXT1__) // does implementation support CRT extensions?
|
||||
return strncpy_s( pDst, bufSize, pSrc, bufSize );
|
||||
#else
|
||||
strncpy( pDst, pSrc, bufSize );
|
||||
return errno;
|
||||
#endif // #if (defined(_MSC_VER) && (_MSC_VER >= 1400)) // is at least VC 2005 compiler?
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \brief Version that mimics the C11 \c strncat_s function.
|
||||
/**
|
||||
* See \c strncat_s of your runtime implementation for documentation!
|
||||
*/
|
||||
inline int mv_strncat_s( char* pDst, const char* pSrc, size_t bufSize )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
#if (defined(_MSC_VER) && (_MSC_VER >= 1400)) // is at least VC 2005 compiler?
|
||||
// '_TRUNCATE' is a Microsoft extension!
|
||||
return strncat_s( pDst, bufSize, pSrc, _TRUNCATE );
|
||||
#elif defined (__STDC_LIB_EXT1__) // does implementation support CRT extensions?
|
||||
return strncat_s( pDst, bufSize, pSrc, bufSize - strnlen_s( pDst, bufSize ) );
|
||||
#else
|
||||
strncat( pDst, pSrc, bufSize );
|
||||
return errno;
|
||||
#endif // #if (defined(_MSC_VER) && (_MSC_VER >= 1400)) // is at least VC 2005 compiler?
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \brief Version that mimics the C11 \c strerror_s function.
|
||||
/**
|
||||
* See \c strerror_s of your runtime implementation for documentation!
|
||||
*/
|
||||
inline int mv_strerror_s( char* pBuf, size_t bufSize, int errnum )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
#if (defined(_MSC_VER) && (_MSC_VER >= 1400)) || defined (__STDC_LIB_EXT1__) // is at least VC 2005 compiler OR implementation supports CRT extensions?
|
||||
return strerror_s( pBuf, bufSize, errnum );
|
||||
#else
|
||||
// Should check the following constraints here:
|
||||
// - pBuf is a null pointer
|
||||
// - bufSize is zero or greater than RSIZE_MAX
|
||||
strncpy( pBuf, strerror( errnum ), bufSize );
|
||||
return errno;
|
||||
#endif // #if (defined(_MSC_VER) && (_MSC_VER >= 1400)) || defined (__STDC_LIB_EXT1__) // is at least VC 2005 compiler OR implementation supports CRT extensions?
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline size_t mv_strerrorlen_s( int errnum )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
#ifdef __STDC_LIB_EXT1__ // does implementation supports CRT extensions?
|
||||
return strerrorlen_s( errnum );
|
||||
#else
|
||||
# if defined(__clang__)
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
# elif defined(_MSC_VER) && (_MSC_VER >= 1800) // is at least VC 2013 compiler?
|
||||
# pragma warning( push )
|
||||
# pragma warning( disable : 4996 ) // 'warning C4996: 'GetVersionExA': was declared deprecated'
|
||||
# endif
|
||||
return strlen( strerror( errnum ) );
|
||||
# if defined(__clang__)
|
||||
# pragma clang diagnostic pop
|
||||
# elif defined(_MSC_VER) && (_MSC_VER >= 1800) // is at least VC 2013 compiler?
|
||||
# pragma warning( pop ) // restore old warning level
|
||||
# endif
|
||||
#endif // #ifdef __STDC_LIB_EXT1__ // does implementation supports CRT extensions?
|
||||
}
|
||||
|
||||
#endif // mvstringH
|
@ -0,0 +1,70 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// (C) Copyright 2005 - 2021 by MATRIX VISION GmbH
|
||||
//
|
||||
// This software is provided by MATRIX VISION GmbH "as is"
|
||||
// and any express or implied warranties, including, but not limited to, the
|
||||
// implied warranties of merchantability and fitness for a particular purpose
|
||||
// are disclaimed.
|
||||
//
|
||||
// In no event shall MATRIX VISION GmbH be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused and
|
||||
// on any theory of liability, whether in contract, strict liability, or tort
|
||||
// (including negligence or otherwise) arising in any way out of the use of
|
||||
// this software, even if advised of the possibility of such damage.
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef function_castH
|
||||
#define function_castH function_castH
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \brief Allows casting void* to a function pointer without gcc complaining.
|
||||
///
|
||||
/// When e.g. compiling code with the \a -pedantic option, gcc will complain about the following
|
||||
/// piece of code
|
||||
///
|
||||
/// \code
|
||||
/// void fn( void )
|
||||
/// {
|
||||
/// void* hMod = dlopen( "mylib", RTLD_LAZY );
|
||||
/// if( hMod )
|
||||
/// {
|
||||
/// typedef void (*myFnPtr)( void );
|
||||
/// myFnPtr p = (myFnPtr)dlsym( hMod, "foobar" ); // this will give a warning
|
||||
/// }
|
||||
/// }
|
||||
/// \endcode
|
||||
///
|
||||
/// The compiler will give you the following warning:
|
||||
///
|
||||
/// \verbatim
|
||||
/// ISO C++ forbids casting between pointer-to-function and pointer-to-object
|
||||
/// \endverbatim
|
||||
///
|
||||
/// That is true, but there is not other way to extract symbols from shared libraries.
|
||||
/// By using this template instead, gcc will be happy and will you.
|
||||
///
|
||||
/// \code
|
||||
/// void fn( void )
|
||||
/// {
|
||||
/// void* hMod = dlopen( "mylib", RTLD_LAZY );
|
||||
/// if( hMod )
|
||||
/// {
|
||||
/// typedef void (*myFnPtr)( void );
|
||||
/// function_cast<myFnPtr> pFunc;
|
||||
/// pFunc.pI = dlsym( hMod, "foobar" );
|
||||
/// myFnPtr p = pFunc.pO;
|
||||
/// }
|
||||
/// }
|
||||
/// \endcode
|
||||
template<typename OutputPtr>
|
||||
union function_cast
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
void* pI;
|
||||
OutputPtr pO;
|
||||
};
|
||||
|
||||
#endif // function_castH
|
@ -0,0 +1,154 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// (C) Copyright 2005 - 2021 by MATRIX VISION GmbH
|
||||
//
|
||||
// This software is provided by MATRIX VISION GmbH "as is"
|
||||
// and any express or implied warranties, including, but not limited to, the
|
||||
// implied warranties of merchantability and fitness for a particular purpose
|
||||
// are disclaimed.
|
||||
//
|
||||
// In no event shall MATRIX VISION GmbH be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused and
|
||||
// on any theory of liability, whether in contract, strict liability, or tort
|
||||
// (including negligence or otherwise) arising in any way out of the use of
|
||||
// this software, even if advised of the possibility of such damage.
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef minmaxH
|
||||
#define minmaxH minmaxH
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <cassert>
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
|
||||
#undef min // otherwise we can't work with the 'numeric_limits' template here as Windows defines a macro 'min'
|
||||
#undef max // otherwise we can't work with the 'numeric_limits' template here as Windows defines a macro 'max'
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename _Ty>
|
||||
_Ty bitMask( _Ty bitCount )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( bitCount >= static_cast<_Ty>( sizeof( _Ty ) * 8 ) )
|
||||
{
|
||||
return _Ty( -1 );
|
||||
}
|
||||
return ( _Ty( 1 ) << bitCount ) - _Ty( 1 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename _Ty>
|
||||
_Ty bitMask_s( _Ty bitCount )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( bitCount > static_cast<_Ty>( sizeof( _Ty ) * 8 ) )
|
||||
{
|
||||
throw std::invalid_argument( "Requested bit mask cannot be stored by target type" );
|
||||
}
|
||||
return bitMask( bitCount );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
template<typename _Ty>
|
||||
bool isPowerOfTwo( _Ty val )
|
||||
//---------------------------------------------------------------------------
|
||||
{
|
||||
return ( ( val > 0 ) && ( ( val & ( val - 1 ) ) == 0 ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename _Ty>
|
||||
_Ty align( _Ty val, _Ty alignment )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( ( alignment <= 0 ) || ( !isPowerOfTwo( alignment ) ) )
|
||||
{
|
||||
throw std::invalid_argument( "align: Invalid alignment" );
|
||||
}
|
||||
return static_cast<_Ty>( ( val + alignment - 1 ) & ( bitMask( static_cast<_Ty>( sizeof( val ) * 8 ) ) - ( alignment - 1 ) ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename _Ty>
|
||||
bool isAligned( _Ty val, _Ty alignment )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( ( alignment <= 0 ) || ( !isPowerOfTwo( alignment ) ) )
|
||||
{
|
||||
throw std::invalid_argument( "isAligned: Invalid alignment" );
|
||||
}
|
||||
return ( ( ( alignment - 1 ) & val ) == 0 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename _Ty, typename _Result>
|
||||
inline _Result getBit( _Ty shift )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( static_cast<_Result>( shift ) > static_cast<_Result>( ( sizeof( _Result ) * 8 ) ) )
|
||||
{
|
||||
throw std::invalid_argument( "shift value too large for this data type" );
|
||||
}
|
||||
return static_cast<_Result>( _Result( 1 ) << _Result( shift ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename _Ty>
|
||||
bool isInRange( const _Ty& lowerLimit, const _Ty& upperLimit, const _Ty& start, const _Ty& end, _Ty* pOverlappingRangeStart = 0, _Ty* pOverlappingRangeEnd = 0 )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( end < lowerLimit )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if( start > upperLimit )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if( pOverlappingRangeStart )
|
||||
{
|
||||
*pOverlappingRangeStart = ( start > lowerLimit ) ? start : lowerLimit;
|
||||
}
|
||||
|
||||
if( pOverlappingRangeEnd )
|
||||
{
|
||||
*pOverlappingRangeEnd = ( end > upperLimit ) ? upperLimit : end;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
#if (defined(_WIN32) || defined(WIN32) || defined(__WIN32__)) && (defined(_WIN64) || defined(WIN64) || defined(__WIN64__))
|
||||
inline const T& saveAssign( const __unaligned T& val, const __unaligned T& min, const __unaligned T& max )
|
||||
#else
|
||||
inline const T& saveAssign( const T& val, const T& min, const T& max )
|
||||
#endif
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return ( ( val > max ) ? max : ( val < min ) ? min : val );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template<typename _Result, typename _Ty>
|
||||
_Result getClippedValue( _Ty val )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( val > static_cast<_Ty>( std::numeric_limits<_Result>::max() ) )
|
||||
{
|
||||
return std::numeric_limits<_Result>::max();
|
||||
}
|
||||
|
||||
if( val < static_cast<_Ty>( std::numeric_limits<_Result>::min() ) )
|
||||
{
|
||||
return std::numeric_limits<_Result>::min();
|
||||
}
|
||||
|
||||
return static_cast<_Result>( val );
|
||||
}
|
||||
|
||||
#endif // minmaxH
|
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.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,112 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// (C) Copyright 2005 - 2021 by MATRIX VISION GmbH
|
||||
//
|
||||
// This software is provided by MATRIX VISION GmbH "as is"
|
||||
// and any express or implied warranties, including, but not limited to, the
|
||||
// implied warranties of merchantability and fitness for a particular purpose
|
||||
// are disclaimed.
|
||||
//
|
||||
// In no event shall MATRIX VISION GmbH be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused and
|
||||
// on any theory of liability, whether in contract, strict liability, or tort
|
||||
// (including negligence or otherwise) arising in any way out of the use of
|
||||
// this software, even if advised of the possibility of such damage.
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#ifndef mvDisplayH
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
# define mvDisplayH mvDisplayH
|
||||
#endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
//---------------------------------------------------------------------------
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
# ifdef _WIN32
|
||||
# ifndef WRAP_ANY
|
||||
# if defined(__BORLANDC__) // is Borland compiler
|
||||
# pragma option -b // force enums to size of integer
|
||||
# endif // #if defined(__BORLANDC__)
|
||||
# ifndef NO_MV_DISPLAY_AUTOLINK
|
||||
# if defined(__BORLANDC__) // is Borland compiler
|
||||
# if __CODEGEARC__ >= 0X710
|
||||
# pragma comment(lib,"mvDisplayb")
|
||||
# else
|
||||
# pragma comment(lib,"mvDisplayb.lib")
|
||||
# endif // #if __CODEGEARC__ >= 0X710
|
||||
# pragma message( "Automatically linking with mvDisplayb.lib" )
|
||||
# elif defined(_MSC_VER) // Microsoft compiler
|
||||
# pragma comment(lib,"mvDisplay.lib")
|
||||
# pragma message( "Automatically linking with mvDisplay.lib" )
|
||||
# endif // #if defined(__BORLANDC__)
|
||||
# endif // #ifndef NO_MV_DISPLAY_AUTOLINK
|
||||
# include <windows.h>
|
||||
# include <windowsx.h>
|
||||
typedef COLORREF ColorValue;
|
||||
# else
|
||||
typedef unsigned int ColorValue;
|
||||
# endif // #ifndef WRAP_ANY
|
||||
# define MV_DISPLAY_API_CALL __stdcall
|
||||
typedef HWND WindowHandle;
|
||||
typedef HDC DeviceContextHandle;
|
||||
typedef HBRUSH BrushHandle;
|
||||
# elif !defined(DOXYGEN_JAVA_DOCUMENTATION) && !defined(DOXYGEN_PYTHON_DOCUMENTATION)
|
||||
# error Unsupported operating system
|
||||
# endif // #ifdef _WIN32
|
||||
#endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
|
||||
#include <mvDisplay/Include/mvDisplayDatatypes.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(MVIMPACT_ACQUIRE_DISPLAY_H_) || defined(DOXYGEN_CPP_DOCUMENTATION)
|
||||
namespace mvIMPACT
|
||||
{
|
||||
namespace acquire
|
||||
{
|
||||
namespace display
|
||||
{
|
||||
#endif // #if defined(MVIMPACT_ACQUIRE_DISPLAY_H_) || defined(DOXYGEN_CPP_DOCUMENTATION)
|
||||
|
||||
#ifndef WRAP_ANY
|
||||
|
||||
/// \brief Prototype for the overlay callback function that can be passed to \b mvDispSetOverlayCallbackFunction()
|
||||
typedef void ( MV_DISPLAY_API_CALL* TImageDisplayOverlayFunction )( DeviceContextHandle hdc, WindowHandle hwnd, int bmpLeft, int bmpTop, int bmpWidth, int bmpHeight, int dispLeft, int dispTop, int dispWidth, int dispHeight, void* pUserParam );
|
||||
|
||||
TDisp* MV_DISPLAY_API_CALL mvDispInit( WindowHandle hwnd );
|
||||
void MV_DISPLAY_API_CALL mvDispDeinit( TDisp** ppDisp );
|
||||
void MV_DISPLAY_API_CALL mvDispClear( TDisp* pDisp );
|
||||
int MV_DISPLAY_API_CALL mvDispGetError( TDisp* pDisp );
|
||||
void MV_DISPLAY_API_CALL mvDispSetBitmapRectangle( TDisp* pDisp, int left, int top, int width, int height );
|
||||
void MV_DISPLAY_API_CALL mvDispSetDisplayMode( TDisp* pDisp, TDisplayMode mode );
|
||||
TDisplayMode MV_DISPLAY_API_CALL mvDispGetDisplayMode( TDisp* pDisp );
|
||||
void MV_DISPLAY_API_CALL mvDispSetDisplayRectangle( TDisp* pDisp, int left, int top, int width, int height );
|
||||
void MV_DISPLAY_API_CALL mvDispSetBackgroundBrush( TDisp* pDisp, HBRUSH hBrush );
|
||||
void MV_DISPLAY_API_CALL mvDispSetDDrawOverlayKeyColor( TDisp* pDisp, COLORREF keyColor );
|
||||
void MV_DISPLAY_API_CALL mvDispSetOverlayCallbackFunction( TDisp* pDisp, TImageDisplayOverlayFunction fctOverlay, void* pUserParam );
|
||||
void MV_DISPLAY_API_CALL mvDispGetImage( TDisp* pDisp, const void** ppData, int* pWidth, int* pHeight, int* pBitsPerPixel, int* pPitch );
|
||||
void MV_DISPLAY_API_CALL mvDispSetImage( TDisp* pDisp, const void* pData, int width, int height, int bitsPerPixel, int pitch );
|
||||
void MV_DISPLAY_API_CALL mvDispSetImageEx( TDisp* pDisp, const void** ppData, size_t ppDataArraySize, TFormatFlags format, int width, int height, int bitsPerPixel, int pitch );
|
||||
void MV_DISPLAY_API_CALL mvDispUpdate( TDisp* pDisp );
|
||||
void MV_DISPLAY_API_CALL mvDispSetWindowHandle( TDisp* pDisp, WindowHandle hwnd );
|
||||
WindowHandle MV_DISPLAY_API_CALL mvDispGetWindowHandle( TDisp* pDisp );
|
||||
void MV_DISPLAY_API_CALL mvDispSetInterpolationMode( TDisp* pDisp, TInterpolationMode interpolationMode );
|
||||
TInterpolationMode MV_DISPLAY_API_CALL mvDispGetInterpolationMode( TDisp* pDisp );
|
||||
int MV_DISPLAY_API_CALL mvDispGetShift( TDisp* pDisp );
|
||||
void MV_DISPLAY_API_CALL mvDispSetShift( TDisp* pDisp, int shift );
|
||||
int MV_DISPLAY_API_CALL mvDispGetAppliedShift( TDisp* pDisp );
|
||||
|
||||
#endif // #ifndef WRAP_ANY
|
||||
|
||||
#if defined(MVIMPACT_ACQUIRE_DISPLAY_H_) || defined(DOXYGEN_CPP_DOCUMENTATION)
|
||||
} // namespace display
|
||||
} // namespace acquire
|
||||
} // namespace mvIMPACT
|
||||
#endif // #if defined(MVIMPACT_ACQUIRE_DISPLAY_H_) || defined(DOXYGEN_CPP_DOCUMENTATION)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // mvDisplayH
|
@ -0,0 +1,197 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// (C) Copyright 2005 - 2021 by MATRIX VISION GmbH
|
||||
//
|
||||
// This software is provided by MATRIX VISION GmbH "as is"
|
||||
// and any express or implied warranties, including, but not limited to, the
|
||||
// implied warranties of merchantability and fitness for a particular purpose
|
||||
// are disclaimed.
|
||||
//
|
||||
// In no event shall MATRIX VISION GmbH be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused and
|
||||
// on any theory of liability, whether in contract, strict liability, or tort
|
||||
// (including negligence or otherwise) arising in any way out of the use of
|
||||
// this software, even if advised of the possibility of such damage.
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef mvDisplayDatatypesH
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
# define mvDisplayDatatypesH mvDisplayDatatypesH
|
||||
#endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if !defined(DOXYGEN_SHOULD_SKIP_THIS) && !defined(WRAP_ANY)
|
||||
# ifdef _WIN32
|
||||
# ifdef __BORLANDC__
|
||||
# pragma option push -b // force enums to the size of integer
|
||||
# endif // __BORLANDC__
|
||||
# endif // _WIN32
|
||||
#endif // #if !defined(DOXYGEN_SHOULD_SKIP_THIS) && !defined(WRAP_ANY)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(MVIMPACT_ACQUIRE_DISPLAY_H_) || defined(DOXYGEN_CPP_DOCUMENTATION)
|
||||
namespace mvIMPACT
|
||||
{
|
||||
namespace acquire
|
||||
{
|
||||
namespace display
|
||||
{
|
||||
#endif // #if defined(MVIMPACT_ACQUIRE_DISPLAY_H_) || defined(DOXYGEN_CPP_DOCUMENTATION)
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/// \brief Defines valid error values for this module.
|
||||
/// \ingroup Display
|
||||
enum TImageDisplayError
|
||||
//---------------------------------------------------------------------------
|
||||
{
|
||||
/// \brief No error occurred since the last time the error code was queried.
|
||||
IDE_NoError = 0,
|
||||
/// \brief There is not enough memory available to perform the requested operation.
|
||||
IDE_OutOfMemory,
|
||||
/// \brief The update failed. This is an internal error.
|
||||
IDE_UpdateFailed,
|
||||
/// \brief One or more of the handles passed to a function where invalid.
|
||||
IDE_InvalidHandle,
|
||||
/// \brief Unspecified internal error.
|
||||
IDE_InternalError,
|
||||
/// \brief Calling a DirectDraw® function did fail.
|
||||
IDE_DirectDrawAccessFailed
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/// \brief Defines valid display modes.
|
||||
/// \ingroup Display
|
||||
enum TDisplayMode
|
||||
//---------------------------------------------------------------------------
|
||||
{
|
||||
/// \brief The default display mode.
|
||||
/**
|
||||
* This display mode is capable of scaling the image. Scaling however will
|
||||
* result in additional CPU load.
|
||||
*
|
||||
* In this mode, the bitmap rectangle will always be scaled to fit into the display rectangle.
|
||||
*
|
||||
* In this mode(and in this mode only) overlay callbacks will be executed.
|
||||
*/
|
||||
DM_Default = 0,
|
||||
/// \brief The fastest display mode.
|
||||
/**
|
||||
* In this mode there will be no scaling and no overlay callbacks but it will
|
||||
* operate with the lowest possible CPU load.
|
||||
*/
|
||||
DM_Fastest,
|
||||
/// \brief DirectDraw® mode.
|
||||
/**
|
||||
* This mode will use DirectDraw® for displaying the image.
|
||||
*
|
||||
* In this mode, the bitmap rectangle will always be scaled to fit into the display rectangle.
|
||||
*/
|
||||
DM_DDrawOverlay,
|
||||
/// \brief Fullscreen (Exclusive) DirectDraw® mode.
|
||||
/**
|
||||
* This mode will use DirectDraw® exclusive mode for displaying the image.
|
||||
*
|
||||
* In this mode, the bitmap rectangle will always be scaled to fit into the display rectangle.
|
||||
*/
|
||||
DM_FullScreen
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/// \brief Defines valid scaler interpolation modes.
|
||||
/// \ingroup Display
|
||||
enum TInterpolationMode
|
||||
//---------------------------------------------------------------------------
|
||||
{
|
||||
/// \brief Nearest neighbor interpolation (default).
|
||||
/**
|
||||
* Fast but with reduced quality.
|
||||
*/
|
||||
IM_NEAREST_NEIGHBOUR = 0,
|
||||
/// \brief Linear interpolation.
|
||||
/**
|
||||
* Both quality and CPU load will be average.
|
||||
*/
|
||||
IM_LINEAR,
|
||||
/// \brief Cubic interpolation.
|
||||
/**
|
||||
* Best quality, highest CPU load.
|
||||
*/
|
||||
IM_CUBIC
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/// \brief Defines valid display pixel formats.
|
||||
/// \ingroup Display
|
||||
enum TFormatFlags
|
||||
//---------------------------------------------------------------------------
|
||||
{
|
||||
/// \brief Valid values for bits per pixel in this format: 15, 16, 24, 32; pData[0] points to the packed image data.
|
||||
ffRGB888xPacked,
|
||||
/// \brief Valid values for bits per pixel in this format: not used, 8 bit per plane, pData[0] points to the Blue, pData[1] points to the Green, pData[2] points to the Red plane.
|
||||
ffRGB888xPlanar,
|
||||
/// \brief Valid values for bits per pixel in this format: 8, 10, 12, 14, 16, LSB aligned.
|
||||
ffMono,
|
||||
/// \brief Valid values for bits per pixel in this format: 16, 20, YUV422: 8-10 bit Y | 8-10 bit U | 8-10 bit Y | 8-10 bit V.
|
||||
ffYUY2,
|
||||
/// \brief Valid values for bits per pixel in this format: not used, YUV422 planar.
|
||||
ffYUV422Planar,
|
||||
/// \brief Valid values for bits per pixel in this format: 30, 36, 42 or 48 10-16 bits per color component RGB packed data.
|
||||
ffRGB2BytePacked,
|
||||
/// \brief Valid values for bits per pixel in this format: 16, 20, YUV422: 8-10 bit U | 8-10 bit Y | 8-10 bit V | 8-10 bit Y.
|
||||
ffUYVY,
|
||||
/// \brief Valid values for bits per pixel in this format: 12, 8 MSB(1), 4 LSBs(1+2), 8MSB(2).
|
||||
ffMonoPacked_V2,
|
||||
/// \brief Valid values for bits per pixel in this format: 15, 16, 24, 32; pData[0] points to the packed image data.
|
||||
ffBGR888xPacked,
|
||||
/// \brief Valid values for bits per pixel in this format: 24 or 48.
|
||||
ffUYV444,
|
||||
/// \brief Valid values for bits per pixel in this format: 48.
|
||||
ffYUV444,
|
||||
/// \brief Valid values for bits per pixel in this format: 30 (R=pix&0x3FF, G=(pix>>10)&0x3FF, B=(pix>>20)&3FF).
|
||||
ffBGR2BytePacked_V2,
|
||||
/// \brief Valid values for bits per pixel in this format: 12, 8 MSB(1), 4 LSB(1) + 4 MSB(2), 8LSB(2).
|
||||
/**
|
||||
* \since 2.5.0
|
||||
*/
|
||||
ffMonoPacked_V1,
|
||||
/// \brief Valid values for bits per pixel in this format: not used, YUV411: 8 bit U | 8 bit Y1 | 8 bit Y2 | 8 bit V | 8 bit Y3 | 8 bit Y4.
|
||||
/**
|
||||
* \since 2.13.0
|
||||
*/
|
||||
ffYUV411_UYYVYY_Packed
|
||||
};
|
||||
|
||||
/// \brief Display structure handle for C compliant interface
|
||||
typedef struct SDisp TDisp;
|
||||
|
||||
#if !defined(DOXYGEN_SHOULD_SKIP_THIS) && !defined(WRAP_ANY)
|
||||
typedef enum TImageDisplayError TImageDisplayError;
|
||||
typedef enum TDisplayMode TDisplayMode;
|
||||
typedef enum TInterpolationMode TInterpolationMode;
|
||||
typedef enum TFormatFlags TFormatFlags;
|
||||
#endif // #if !defined(DOXYGEN_SHOULD_SKIP_THIS) && !defined(WRAP_ANY)
|
||||
|
||||
#if defined(MVIMPACT_ACQUIRE_DISPLAY_H_) || defined(DOXYGEN_CPP_DOCUMENTATION)
|
||||
} // namespace display
|
||||
} // namespace acquire
|
||||
} // namespace mvIMPACT
|
||||
#endif // #if defined(MVIMPACT_ACQUIRE_DISPLAY_H_) || defined(DOXYGEN_CPP_DOCUMENTATION)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
// restore Borland compiler switch 'force enums to the size of integer'
|
||||
#if !defined(DOXYGEN_SHOULD_SKIP_THIS) && !defined(WRAP_ANY)
|
||||
# ifdef _WIN32
|
||||
# ifdef __BORLANDC__
|
||||
# pragma option pop
|
||||
# endif // __BORLANDC__
|
||||
# endif // _WIN32
|
||||
#endif // #if !defined(DOXYGEN_SHOULD_SKIP_THIS) && !defined(WRAP_ANY)
|
||||
|
||||
#endif // mvDisplayDatatypesH
|
@ -0,0 +1,113 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// (C) Copyright 2005 - 2021 by MATRIX VISION GmbH
|
||||
//
|
||||
// This software is provided by MATRIX VISION GmbH "as is"
|
||||
// and any express or implied warranties, including, but not limited to, the
|
||||
// implied warranties of merchantability and fitness for a particular purpose
|
||||
// are disclaimed.
|
||||
//
|
||||
// In no event shall MATRIX VISION GmbH be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused and
|
||||
// on any theory of liability, whether in contract, strict liability, or tort
|
||||
// (including negligence or otherwise) arising in any way out of the use of
|
||||
// this software, even if advised of the possibility of such damage.
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#ifndef mvDisplayExtensionsH
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
# define mvDisplayExtensionsH mvDisplayExtensionsH
|
||||
#endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
//---------------------------------------------------------------------------
|
||||
#include <mvDisplay/Include/mvDisplay.h>
|
||||
#ifdef __cplusplus
|
||||
# include <mvIMPACT_CPP/mvIMPACT_acquire.h>
|
||||
#else
|
||||
# include <mvDeviceManager/Include/mvDeviceManager.h>
|
||||
#endif // __cplusplus
|
||||
|
||||
#if defined(MVIMPACT_ACQUIRE_DISPLAY_H_) || defined(DOXYGEN_CPP_DOCUMENTATION)
|
||||
namespace mvIMPACT
|
||||
{
|
||||
namespace acquire
|
||||
{
|
||||
namespace display
|
||||
{
|
||||
#endif // #if defined(MVIMPACT_ACQUIRE_DISPLAY_H_) || defined(DOXYGEN_CPP_DOCUMENTATION)
|
||||
|
||||
#ifndef WRAP_ANY
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void MV_DISPLAY_API_CALL mvDispConvertFormat( TImageBufferPixelFormat pixelFormat, TFormatFlags* pFormat, int* pBitsPerPixel );
|
||||
void MV_DISPLAY_API_CALL mvDispSetImageFromImageBuffer( TDisp* pDisp, const ImageBuffer* pBuf );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#ifdef __cplusplus
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \brief Sets the next image to display.
|
||||
/**
|
||||
* This function can deal with any pixel format supported by mvIMPACT Acquire.
|
||||
* \since 1.12.68
|
||||
*/
|
||||
inline void mvDispSetImageFromRequest(
|
||||
/// [in] A handle to a display structure obtained
|
||||
/// from a successful call to \b mvDispInit().
|
||||
TDisp* pDisp,
|
||||
/// [in] The request object that shall be displayed.
|
||||
const mvIMPACT::acquire::Request* pRequest )
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( pRequest )
|
||||
{
|
||||
const size_t MAX_PLANE_CNT = 3;
|
||||
size_t planeCount = 1;
|
||||
const void* dataPtrArray[MAX_PLANE_CNT];
|
||||
char* p = ( char* )pRequest->imageData.read();
|
||||
int bitsPerPixel = 8;
|
||||
TFormatFlags format = ffMono;
|
||||
|
||||
mvDispConvertFormat( static_cast<TImageBufferPixelFormat>( pRequest->imagePixelFormat.read() ), &format, &bitsPerPixel );
|
||||
switch( pRequest->imagePixelFormat.read() )
|
||||
{
|
||||
case ibpfRGB888Planar:
|
||||
case ibpfRGBx888Planar:
|
||||
dataPtrArray[2] = p + pRequest->imageChannelOffset.read( 0 );
|
||||
dataPtrArray[1] = p + pRequest->imageChannelOffset.read( 1 );
|
||||
dataPtrArray[0] = p + pRequest->imageChannelOffset.read( 2 );
|
||||
planeCount = 3;
|
||||
break;
|
||||
case ibpfYUV422Planar:
|
||||
dataPtrArray[0] = p + pRequest->imageChannelOffset.read( 0 );
|
||||
dataPtrArray[1] = p + pRequest->imageChannelOffset.read( 1 );
|
||||
dataPtrArray[2] = p + pRequest->imageChannelOffset.read( 2 );
|
||||
planeCount = 3;
|
||||
break;
|
||||
default:
|
||||
dataPtrArray[0] = p;
|
||||
break;
|
||||
}
|
||||
mvDispSetImageEx( pDisp, dataPtrArray, planeCount, format, pRequest->imageWidth.read(), pRequest->imageHeight.read(), bitsPerPixel, pRequest->imageLinePitch.read() );
|
||||
}
|
||||
else
|
||||
{
|
||||
mvDispSetImage( pDisp, 0, 0, 0, 8, 0 );
|
||||
}
|
||||
}
|
||||
#endif // #ifdef __cplusplus
|
||||
|
||||
#endif // #ifndef WRAP_ANY
|
||||
|
||||
#if defined(MVIMPACT_ACQUIRE_DISPLAY_H_) || defined(DOXYGEN_CPP_DOCUMENTATION)
|
||||
} // namespace display
|
||||
} // namespace acquire
|
||||
} // namespace mvIMPACT
|
||||
#endif // #if defined(MVIMPACT_ACQUIRE_DISPLAY_H_) || defined(DOXYGEN_CPP_DOCUMENTATION)
|
||||
|
||||
#endif // mvDisplayExtensionsH
|
@ -0,0 +1,67 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// (C) Copyright 2005 - 2021 by MATRIX VISION GmbH
|
||||
//
|
||||
// This software is provided by MATRIX VISION GmbH "as is"
|
||||
// and any express or implied warranties, including, but not limited to, the
|
||||
// implied warranties of merchantability and fitness for a particular purpose
|
||||
// are disclaimed.
|
||||
//
|
||||
// In no event shall MATRIX VISION GmbH be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused and
|
||||
// on any theory of liability, whether in contract, strict liability, or tort
|
||||
// (including negligence or otherwise) arising in any way out of the use of
|
||||
// this software, even if advised of the possibility of such damage.
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#ifndef mvDisplayWindowH
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
# define mvDisplayWindowH mvDisplayWindowH
|
||||
#endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
//---------------------------------------------------------------------------
|
||||
#include <mvDisplay/Include/mvDisplay.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(MVIMPACT_ACQUIRE_DISPLAY_H_) || defined(DOXYGEN_CPP_DOCUMENTATION)
|
||||
namespace mvIMPACT
|
||||
{
|
||||
namespace acquire
|
||||
{
|
||||
namespace display
|
||||
{
|
||||
#endif // #if defined(MVIMPACT_ACQUIRE_DISPLAY_H_) || defined(DOXYGEN_CPP_DOCUMENTATION)
|
||||
|
||||
/// \brief Display window handle for C compliant interface.
|
||||
typedef void* HDISP;
|
||||
|
||||
#ifndef WRAP_ANY
|
||||
|
||||
/// \brief Prototype for the callback function that can be passed to \b mvDispWindowSetMessageHandler()
|
||||
typedef void ( *TPreProcessMessage )( HDISP hDisp, UINT message, WPARAM wParam, LPARAM lParam );
|
||||
|
||||
void MV_DISPLAY_API_CALL mvDispWindowDestroy( HDISP hDisp );
|
||||
WindowHandle MV_DISPLAY_API_CALL mvDispWindowGetWindowHandle( HDISP hDisp );
|
||||
TDisp* MV_DISPLAY_API_CALL mvDispWindowGetDisplayHandle( HDISP hDisp );
|
||||
HDISP MV_DISPLAY_API_CALL mvDispWindowCreate( const char* title );
|
||||
int MV_DISPLAY_API_CALL mvDispWindowSetRefreshTime( HDISP hDisp, int time_ms );
|
||||
void MV_DISPLAY_API_CALL mvDispWindowShow( HDISP hDisp );
|
||||
void MV_DISPLAY_API_CALL mvDispWindowSetMessageHandler( HDISP hDisp, TPreProcessMessage handler );
|
||||
TPreProcessMessage MV_DISPLAY_API_CALL mvDispWindowGetMessageHandler( HDISP hDisp );
|
||||
|
||||
#endif // #ifndef WRAP_ANY
|
||||
|
||||
#if defined(MVIMPACT_ACQUIRE_DISPLAY_H_) || defined(DOXYGEN_CPP_DOCUMENTATION)
|
||||
} // namespace display
|
||||
} // namespace acquire
|
||||
} // namespace mvIMPACT
|
||||
#endif // #if defined(MVIMPACT_ACQUIRE_DISPLAY_H_) || defined(DOXYGEN_CPP_DOCUMENTATION)
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // mvDisplayWindowH
|
@ -0,0 +1,666 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// (C) Copyright 2005 - 2021 by MATRIX VISION GmbH
|
||||
//
|
||||
// This software is provided by MATRIX VISION GmbH "as is"
|
||||
// and any express or implied warranties, including, but not limited to, the
|
||||
// implied warranties of merchantability and fitness for a particular purpose
|
||||
// are disclaimed.
|
||||
//
|
||||
// In no event shall MATRIX VISION GmbH be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused and
|
||||
// on any theory of liability, whether in contract, strict liability, or tort
|
||||
// (including negligence or otherwise) arising in any way out of the use of
|
||||
// this software, even if advised of the possibility of such damage.
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef MVIMPACT_ACQUIRE_DISPLAY_H_
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
# define MVIMPACT_ACQUIRE_DISPLAY_H_ MVIMPACT_ACQUIRE_DISPLAY_H_
|
||||
#endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifdef SWIG
|
||||
# ifdef SWIGPYTHON
|
||||
# ifndef WRAP_PYTHON
|
||||
# define WRAP_PYTHON
|
||||
# endif
|
||||
# endif
|
||||
# ifdef SWIGJAVA
|
||||
# ifndef WRAP_JAVA
|
||||
# define WRAP_JAVA
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef WRAP_PYTHON
|
||||
# ifndef PYTHON_ONLY
|
||||
# define PYTHON_ONLY(X) X
|
||||
# endif
|
||||
# ifndef PYTHON_CPP_SWITCH
|
||||
# define PYTHON_CPP_SWITCH(PYTHON_WRAPPER_CODE,CPP_WRAPPER_CODE) PYTHON_WRAPPER_CODE
|
||||
# endif
|
||||
# ifndef WRAP_ANY
|
||||
# define WRAP_ANY
|
||||
# endif // #ifndef WRAP_ANY
|
||||
#else // #ifdef WRAP_PYTHON
|
||||
# ifndef PYTHON_ONLY
|
||||
# define PYTHON_ONLY(X)
|
||||
# endif
|
||||
# ifndef PYTHON_CPP_SWITCH
|
||||
# define PYTHON_CPP_SWITCH(PYTHON_WRAPPER_CODE,CPP_WRAPPER_CODE) CPP_WRAPPER_CODE
|
||||
# endif
|
||||
#endif // #ifdef WRAP_PYTHON
|
||||
|
||||
#ifdef WRAP_JAVA
|
||||
# ifndef JAVA_ONLY
|
||||
# define JAVA_ONLY(X) X
|
||||
# endif
|
||||
# ifndef JAVA_CPP_SWITCH
|
||||
# define JAVA_CPP_SWITCH(JAVA_WRAPPER_CODE,CPP_WRAPPER_CODE) JAVA_WRAPPER_CODE
|
||||
# endif
|
||||
# ifndef WRAP_ANY
|
||||
# define WRAP_ANY
|
||||
# endif // #ifndef WRAP_ANY
|
||||
#else // #ifdef WRAP_JAVA
|
||||
# ifndef JAVA_ONLY
|
||||
# define JAVA_ONLY(X)
|
||||
# endif
|
||||
# ifndef JAVA_CPP_SWITCH
|
||||
# define JAVA_CPP_SWITCH(JAVA_WRAPPER_CODE,CPP_WRAPPER_CODE) CPP_WRAPPER_CODE
|
||||
# endif
|
||||
#endif // #ifdef WRAP_JAVA
|
||||
|
||||
#if defined(WRAP_PYTHON) || defined(WRAP_JAVA)
|
||||
# ifndef PYTHON_OR_JAVA_ONLY
|
||||
# define PYTHON_OR_JAVA_ONLY(X) X
|
||||
# endif
|
||||
#else
|
||||
# ifndef PYTHON_OR_JAVA_ONLY
|
||||
# define PYTHON_OR_JAVA_ONLY(X)
|
||||
# endif
|
||||
#endif // #if defined(WRAP_PYTHON) || defined(WRAP_JAVA)
|
||||
|
||||
#ifdef _MSC_VER // is Microsoft compiler?
|
||||
# pragma warning( push )
|
||||
# if _MSC_VER < 1300 // is 'old' VC 6 compiler?
|
||||
# pragma warning( disable : 4786 ) // 'identifier was truncated to '255' characters in the debug information'
|
||||
# define __FUNCTION__ "No function name information as the __FUNCTION__ macro is not supported by this(VC 6) compiler"
|
||||
# pragma message( "WARNING: This header(" __FILE__ ") uses the __FUNCTION__ macro, which is not supported by this compiler. A default definition(\"" __FUNCTION__ "\") will be used!" )
|
||||
# pragma message( "WARNING: This header(" __FILE__ ") uses inheritance for exception classes. However this compiler can't handle this correctly. Trying to catch a specific exception by writing a catch block for a base class will not work!" )
|
||||
# endif // #if _MSC_VER < 1300
|
||||
# pragma warning( disable : 4512 ) // 'assignment operator could not be generated' (reason: assignment operators declared 'private' but not implemented)
|
||||
#endif // #ifdef _MSC_VER
|
||||
|
||||
#ifndef WRAP_ANY
|
||||
# include <string>
|
||||
#endif // #ifdef WRAP_ANY
|
||||
|
||||
// C-API header will be imported into mvIMPACT::acquire::display if included from here
|
||||
#include <mvDisplay/Include/mvDisplayWindow.h>
|
||||
#ifdef MVIMPACT_ACQUIRE_H_
|
||||
# include <mvDisplay/Include/mvDisplayExtensions.h>
|
||||
# if defined(CPP_STANDARD_VERSION) && (CPP_STANDARD_VERSION >= 11)
|
||||
# include <memory>
|
||||
# endif // #if defined(CPP_STANDARD_VERSION) && (CPP_STANDARD_VERSION >= 11)
|
||||
#endif // #ifdef MVIMPACT_ACQUIRE_H_
|
||||
|
||||
#if defined(MVIMPACT_ACQUIRE_HELPER_H) && (!defined(CPP_STANDARD_VERSION) || ( defined(CPP_STANDARD_VERSION) && (CPP_STANDARD_VERSION < 11)))
|
||||
# error "Combining the mvIMPACT_acquire_helper.h and mvIMPACT_acquire_display.h requires 'CPP_STANDARD_VERSION' being defined and set to a minimal value of 11! See documentation of the class mvIMPACT::acquire::helper::RequestProvider for details."
|
||||
#endif // #if defined(MVIMPACT_ACQUIRE_HELPER_H) && (!defined(CPP_STANDARD_VERSION) || ( defined(CPP_STANDARD_VERSION) && (CPP_STANDARD_VERSION < 11)))
|
||||
|
||||
namespace mvIMPACT
|
||||
{
|
||||
namespace acquire
|
||||
{
|
||||
/// \namespace mvIMPACT::acquire::display This namespace contains classes and functions that can be used to display images.
|
||||
namespace display
|
||||
{
|
||||
|
||||
/// \defgroup Display Display functions
|
||||
/// \brief Classes and functions that can be used to display images.
|
||||
/**
|
||||
* This group contains classes and functions that can be used to display images.
|
||||
*/
|
||||
/// @{
|
||||
|
||||
class ImageDisplayWindow;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \brief A class that can be used for displaying images within existing windows or GUI elements that can provide a window handle.
|
||||
/**
|
||||
* Instances of this class can be associated with an existing window object of
|
||||
* which the window handle is known and can be passed to the constructor of this
|
||||
* class.
|
||||
*
|
||||
* \image html Display_Window.png
|
||||
*
|
||||
* The full client area of a window will be consumed by a display object. Where the actual image shall be display relative
|
||||
* to the upper left corner of the windows client area can be defined by calling \b mvIMPACT::acquire::display::ImageDisplay::SetDisplayRectangle(). This function
|
||||
* will also limit the area where image data will be displayed. The area outside the display rectangle but within the
|
||||
* windows client area can be filled by defining a background brush and then attach this brush to the display by calling
|
||||
* \b mvIMPACT::acquire::display::ImageDisplay::SetBackgroundBrush().
|
||||
*
|
||||
* If the actual image size differs from the area defined by \b mvIMPACT::acquire::display::ImageDisplay::SetDisplayRectangle(), it depends on the display mode
|
||||
* if the complete image is scaled, cropped of just drawn in the top left corner of the display rectangle. The display mode
|
||||
* can be modified by calling \b mvIMPACT::acquire::display::ImageDisplay::SetDisplayMode().
|
||||
*
|
||||
* In addition to that only a part of the actual image can be selected for drawing by the function \b mvIMPACT::acquire::display::ImageDisplay::SetBitmapRectangle().
|
||||
* For this region the same scaling and cropping regions will be applied then.
|
||||
*
|
||||
* \if DOXYGEN_CPP_DOCUMENTATION
|
||||
* \note
|
||||
* This class can be used without using the rest of %mvIMPACT Acquire. This is achieved by using a pre-processor check
|
||||
* for the presence of a certain include guard that is defined by %mvIMPACT Acquire. Now in order to be able to use those
|
||||
* functions, that can directly work on data types as defined by %mvIMPACT Acquire, the main %mvIMPACT Acquire header
|
||||
* must be included \b BEFORE including this header:
|
||||
*
|
||||
* \code
|
||||
* #include <mvIMPACT_CPP/mvIMPACT_acquire.h>
|
||||
* #include <mvDisplay/Include/mvIMPACT_acquire_display.h>
|
||||
* \endcode
|
||||
* \endif
|
||||
*
|
||||
* \sa
|
||||
* <b>mvIMPACT::acquire::display::ImageDisplay::SetDisplayRectangle(),<br>
|
||||
* mvIMPACT::acquire::display::ImageDisplay::SetBitmapRectangle(),<br>
|
||||
* mvIMPACT::acquire::display::ImageDisplay::SetBackgroundBrush(),<br>
|
||||
* mvIMPACT::acquire::display::ImageDisplay::SetDisplayMode()</b>
|
||||
*/
|
||||
class ImageDisplay
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
friend class ImageDisplayWindow;
|
||||
TDisp* pDisp_;
|
||||
bool boMustFree_;
|
||||
#if defined(MVIMPACT_ACQUIRE_H_)
|
||||
# if defined( CPP_STANDARD_VERSION ) && ( CPP_STANDARD_VERSION >= 11 )
|
||||
std::shared_ptr<Request> pCurrentRequest_;
|
||||
# endif // #if defined( CPP_STANDARD_VERSION ) && ( CPP_STANDARD_VERSION >= 11 )
|
||||
#endif // #if defined(MVIMPACT_ACQUIRE_H_) || defined(DOXYGEN_CPP_DOCUMENTATION)
|
||||
explicit ImageDisplay() : pDisp_( 0 ), boMustFree_( false ) {}
|
||||
public:
|
||||
/// \brief Create a new object that can be used for displaying images
|
||||
explicit ImageDisplay(
|
||||
/// A handle to the window which should be used for the displaying.
|
||||
WindowHandle hwnd ) : pDisp_( 0 ), boMustFree_( true )
|
||||
{
|
||||
pDisp_ = mvDispInit( hwnd );
|
||||
}
|
||||
/// \brief Frees the resources previously allocated.
|
||||
~ImageDisplay()
|
||||
{
|
||||
if( boMustFree_ )
|
||||
{
|
||||
mvDispDeinit( &pDisp_ );
|
||||
}
|
||||
}
|
||||
/// \brief Clears the display.
|
||||
/**
|
||||
* Either the windows default background will be displayed afterwards or if a
|
||||
* background brush has been defined the background brush will be used to fill
|
||||
* the complete client area.
|
||||
*
|
||||
* \sa
|
||||
* <b>mvIMPACT::acquire::display::ImageDisplay::SetBackgroundBrush()</b>
|
||||
*/
|
||||
void Clear( void ) const
|
||||
{
|
||||
mvDispClear( pDisp_ );
|
||||
}
|
||||
/// \brief Sets the position and dimension of bitmap data region.
|
||||
/**
|
||||
* This defines the area relative within the area consumed by the window associated with
|
||||
* the window handle that is bound to this display. See \b mvIMPACT::acquire::display::ImageDisplay for a detailed
|
||||
* description on how to define the different rectangles and areas for drawing.
|
||||
*
|
||||
* \sa
|
||||
* <b>mvIMPACT::acquire::display::ImageDisplay<br>
|
||||
* mvIMPACT::acquire::display::ImageDisplay::SetDisplayRectangle()</b>
|
||||
*/
|
||||
void SetBitmapRectangle(
|
||||
/// [in] The left offset of the rectangle.
|
||||
int left,
|
||||
/// [in] The top offset of the rectangle.
|
||||
int top,
|
||||
/// [in] The width of the bitmap rectangle.
|
||||
int width,
|
||||
/// [in] The height of the rectangle.
|
||||
int height )
|
||||
{
|
||||
mvDispSetBitmapRectangle( pDisp_, left, top, width, height );
|
||||
}
|
||||
/// \brief Defines the rectangle used for drawing within the window associated with the display structure.
|
||||
/**
|
||||
* This function can be used to define a rectangle within the defined window
|
||||
* Only this then will be used for drawing. This window can be smaller than the image
|
||||
* defined by \b mvIMPACT::acquire::display::ImageDisplay::SetImage(). Then just a part of the image
|
||||
* will be displayed when in \b mvIMPACT::acquire::display::DM_Fastest or the whole image will be scaled
|
||||
* down to fit into the rectangle when in \b mvIMPACT::acquire::display::DM_Default mode.
|
||||
*
|
||||
* When the display rectangle is larger than the image the image will be placed in the lower left
|
||||
* corner of the display rectangle (either scaled or unscaled). See \b ImageDisplay for a detailed
|
||||
* description on how to define the different rectangles and areas for drawing.
|
||||
*
|
||||
* \sa
|
||||
* <b>mvIMPACT::acquire::display::ImageDisplay,<br>
|
||||
* mvIMPACT::acquire::display::ImageDisplay::SetBitmapRectangle</b>
|
||||
*/
|
||||
void SetDisplayRectangle(
|
||||
/// [in] The left offset within the window.
|
||||
int left,
|
||||
/// [in] The top offset within the window.
|
||||
int top,
|
||||
/// [in] The width of the rectangle to use for drawing.
|
||||
int width,
|
||||
/// [in] The height of the rectangle to use for drawing.
|
||||
int height )
|
||||
{
|
||||
mvDispSetDisplayRectangle( pDisp_, left, top, width, height );
|
||||
}
|
||||
/// \brief Gets the parameters of the current data block associated with the display.
|
||||
/**
|
||||
* If a parameter is not needed it might be 0(NULL).
|
||||
*
|
||||
* The data returned will always be in packed format.
|
||||
*/
|
||||
void GetImage(
|
||||
/// [out] A pointer to a variable to receive the storage location of the pixel data.
|
||||
/// This can be 0 if the value is not needed.
|
||||
const void** ppData,
|
||||
/// [out] A pointer to a variable to receive the width of the current image.
|
||||
/// This can be 0 if the value is not needed.
|
||||
int* pWidth,
|
||||
/// [out] A pointer to a variable to receive the height of the current image.
|
||||
/// This can be 0 if the value is not needed.
|
||||
int* pHeight,
|
||||
/// [out] A pointer to a variable to receive the bits per pixel of the current image.
|
||||
/// This can be 0 if the value is not needed.
|
||||
int* pBitsPerPixel,
|
||||
/// [out] A pointer to a variable to receive the pitch (bytes per pixel * width in pixel)of the current image.
|
||||
/// This can be 0 if the value is not needed.
|
||||
int* pPitch )
|
||||
{
|
||||
mvDispGetImage( pDisp_, ppData, pWidth, pHeight, pBitsPerPixel, pPitch );
|
||||
}
|
||||
/// \brief Sets the next image to display.
|
||||
/**
|
||||
* This function can deal with RGB888x packed images, 8 bit grey-scale images
|
||||
* and 16 bit Packed RGB images. For other formats overloaded versions of this function
|
||||
* must be used.
|
||||
*/
|
||||
void SetImage(
|
||||
/// [in] A pointer to the address of the pixel data.
|
||||
const void* pData,
|
||||
/// [in] The width of the image.
|
||||
int width,
|
||||
/// [in] The height of the image.
|
||||
int height,
|
||||
/// [in] The number of bits per pixel.
|
||||
int bitsPerPixel,
|
||||
/// [in] The pitch in bytes of one line of pixel data (bytes per pixel * width in pixel per line).
|
||||
int pitch )
|
||||
{
|
||||
mvDispSetImage( pDisp_, pData, width, height, bitsPerPixel, pitch );
|
||||
}
|
||||
/// \brief Sets the next image to display.
|
||||
void SetImage(
|
||||
/// [in] An array of pointers that point to the actual image data
|
||||
/// For planar RGB images e.g. this can be 3 pointers each pointing
|
||||
/// to one color plane.
|
||||
const void** ppData,
|
||||
/// [in] The number of pointers passed via \a ppData.
|
||||
size_t ppDataArraySize,
|
||||
/// [in] The pixel format as defined by \b mvIMPACT::acquire::display::TFormatFlags.
|
||||
TFormatFlags format,
|
||||
/// [in] The width of the image.
|
||||
int width,
|
||||
/// [in] The height of the image.
|
||||
int height,
|
||||
/// [in] The number of bits per pixel.
|
||||
int bitsPerPixel,
|
||||
/// [in] The pitch in bytes of one line of pixel data (bytes per pixel * width in pixel per line).
|
||||
int pitch )
|
||||
{
|
||||
mvDispSetImageEx( pDisp_, ppData, ppDataArraySize, format, width, height, bitsPerPixel, pitch );
|
||||
}
|
||||
#if defined(MVIMPACT_ACQUIRE_H_) || defined(DOXYGEN_CPP_DOCUMENTATION)
|
||||
/// \brief Sets the next image to display.
|
||||
/**
|
||||
* This function can deal with any pixel format supported by %mvIMPACT Acquire.
|
||||
*/
|
||||
void SetImage(
|
||||
/// [in] The image buffer object that shall be displayed.
|
||||
const mvIMPACT::acquire::ImageBuffer* pBuf )
|
||||
{
|
||||
mvDispSetImageFromImageBuffer( pDisp_, pBuf );
|
||||
}
|
||||
/// \brief Sets the next image to display.
|
||||
/**
|
||||
* This function can deal with any pixel format supported by %mvIMPACT Acquire.
|
||||
*/
|
||||
void SetImage(
|
||||
/// [in] The \b mvIMPACT::acquire::Request object whose image data shall be displayed.
|
||||
const mvIMPACT::acquire::Request* pRequest )
|
||||
{
|
||||
mvDispSetImageFromRequest( pDisp_, pRequest );
|
||||
}
|
||||
# if (defined( CPP_STANDARD_VERSION ) && ( CPP_STANDARD_VERSION >= 11 )) || defined(DOXYGEN_CPP_DOCUMENTATION)
|
||||
/// \brief Sets the next image to display.
|
||||
/**
|
||||
* This function can deal with any pixel format supported by %mvIMPACT Acquire.
|
||||
*/
|
||||
void SetImage(
|
||||
/// [in] The \b mvIMPACT::acquire::Request object whose image data shall be displayed.
|
||||
std::shared_ptr<Request> pRequest )
|
||||
{
|
||||
pCurrentRequest_ = pRequest;
|
||||
mvDispSetImageFromRequest( pDisp_, pRequest.get() );
|
||||
}
|
||||
# endif // #if (defined( CPP_STANDARD_VERSION ) && ( CPP_STANDARD_VERSION >= 11 )) || defined(DOXYGEN_CPP_DOCUMENTATION)
|
||||
#endif // #if defined(MVIMPACT_ACQUIRE_H_) || defined(DOXYGEN_CPP_DOCUMENTATION)
|
||||
/// \brief Removes the current image from the display.
|
||||
/**
|
||||
* This function will remove the current image attached to the display from the display again.
|
||||
* This is mainly meant to be able to free the memory associated with the image buffer without the risk that a
|
||||
* later call to an update function or a repaint message would cause another redraw of then
|
||||
* freed memory. As only one buffer can be attached to a display at any given time calling
|
||||
* \b mvIMPACT::acquire::display::ImageDisplay::SetImage will effectively remove the previous
|
||||
* image as well so this function usually is only needed when ending e.g. a live display.
|
||||
*/
|
||||
void RemoveImage( void )
|
||||
{
|
||||
mvDispSetImage( pDisp_, 0, 0, 0, 0, 0 );
|
||||
#if defined(MVIMPACT_ACQUIRE_H_)
|
||||
# if defined( CPP_STANDARD_VERSION ) && ( CPP_STANDARD_VERSION >= 11 )
|
||||
pCurrentRequest_.reset();
|
||||
# endif // #if defined( CPP_STANDARD_VERSION ) && ( CPP_STANDARD_VERSION >= 11 )
|
||||
#endif // #if defined(MVIMPACT_ACQUIRE_H_)
|
||||
}
|
||||
/// \brief Immediately redraws the current image.
|
||||
void Update( void ) const
|
||||
{
|
||||
mvDispUpdate( pDisp_ );
|
||||
}
|
||||
/// \brief Returns the current display mode.
|
||||
/**
|
||||
* Valid display modes are defined by \b mvIMPACT::acquire::display::TDisplayMode.
|
||||
* \return
|
||||
* The current display mode.
|
||||
*/
|
||||
TDisplayMode GetDisplayMode( void ) const
|
||||
{
|
||||
return mvDispGetDisplayMode( pDisp_ );
|
||||
}
|
||||
/// \brief Switches to a different display mode.
|
||||
void SetDisplayMode(
|
||||
/// [in] The new display mode.
|
||||
TDisplayMode mode )
|
||||
{
|
||||
mvDispSetDisplayMode( pDisp_, mode );
|
||||
}
|
||||
/// \brief Gets the current interpolation mode that will be used for scaling if display window rectangle is different to input image rectangle.
|
||||
/**
|
||||
* Valid interpolation modes are defined by \b mvIMPACT::acquire::display::TInterpolationMode.
|
||||
* \return The current interpolation mode.
|
||||
*/
|
||||
TInterpolationMode GetInterpolationMode( void ) const
|
||||
{
|
||||
return mvDispGetInterpolationMode( pDisp_ );
|
||||
}
|
||||
/// \brief Sets the new interpolation mode that will be used for scaling if display window rectangle is different to input image rectangle.
|
||||
void SetInterpolationMode(
|
||||
/// [in] The new interpolation mode.
|
||||
TInterpolationMode mode )
|
||||
{
|
||||
mvDispSetInterpolationMode( pDisp_, mode );
|
||||
}
|
||||
/// \brief Returns the current shift value as defined by the application.
|
||||
/**
|
||||
* This function returns the current shift value as defined by the application by previous
|
||||
* calls to \b mvIMPACT::acquire::display::ImageDisplay::SetShift. See \b mvIMPACT::acquire::display::ImageDisplay::SetShift for a detailed explanation
|
||||
* about the display behaviour when applying custom shift values.
|
||||
*
|
||||
* \sa
|
||||
* <b>mvIMPACT::acquire::display::ImageDisplay::SetShift,<br>
|
||||
* mvIMPACT::acquire::display::ImageDisplay::GetAppliedShift</b>
|
||||
* \since 2.4.0
|
||||
* \return The current shift value from previous calls to \b mvIMPACT::acquire::display::ImageDisplay::SetShift.
|
||||
*/
|
||||
int GetShift( void ) const
|
||||
{
|
||||
return mvDispGetShift( pDisp_ );
|
||||
}
|
||||
/// \brief Sets the shift value that shall be subtracted from the shift value needed to display the 8 msb of a pixel.
|
||||
/**
|
||||
* This function will allow to select which 8 bits out of a multi-byte pixel format shall be displayed the
|
||||
* next time \b mvIMPACT::acquire::display::ImageDisplay::Update is called. When the \a shift value is 0 the 8 msb of each pixel will be displayed
|
||||
* so e.g. for a 12 bit format bits 11 to 4 will be displayed by default.
|
||||
*
|
||||
* Consider the typical layout of 12 mono pixel data in memory:
|
||||
*
|
||||
* \image html Mono12_01.png
|
||||
*
|
||||
* So with an application defined \a shift value of 0 (the default), the display module will shift each
|
||||
* 2 byte pixel by 4 positions to the right. This will remove the 4 lsb from the data. Afterwards the now
|
||||
* empty upper byte of each pixel is removed from the data resulting in the following memory layout which is
|
||||
* then displayed on the canvas:
|
||||
*
|
||||
* \image html Mono12_02.png
|
||||
*
|
||||
* Now sometimes it is required to display other bits from the image e.g. for analysis purposes. As most operating
|
||||
* systems only support to display 8 bits per color component this requires to select a different range of pixels to
|
||||
* be send to the canvas. This can be done by calling this function and passing a custom \a shift value to it. The
|
||||
* custom \a shift value will be subtracted from the value that would be needed to display the 8 msb for a given format.
|
||||
*
|
||||
* So to display the 8 lsb for a 12 bit mono format, \a shift must be set to 4. This then results in the display module to
|
||||
* use a actual shift value of 4(required to display the 8 msb) - 4(defined by calling this function) = 0. Then removing
|
||||
* the upper byte from each pixel results in only the 8 lsb of each pixel being displayed.
|
||||
*
|
||||
* When e.g. setting \a shift to 3 for a 12 bit mono for would result in bits 8 - 1 to be displayed:
|
||||
*
|
||||
* \image html Mono12_03.png
|
||||
*
|
||||
* The shift value that has actually been applied the last time an image has been displayed (thus '1' when taking the
|
||||
* example in the image above (4(required) - 3(defined))) can be queried by calling \b mvIMPACT::acquire::display::ImageDisplay::GetAppliedShift.
|
||||
*
|
||||
* \note
|
||||
* During the conversion from a multi-byte to a single byte format the pixel data will be clipped to 255 if
|
||||
* a pixel value is larger than what can be stored in a single byte after the shift operation.
|
||||
*
|
||||
* \sa
|
||||
* <b>mvIMPACT::acquire::display::ImageDisplay::GetShift,<br>
|
||||
* mvIMPACT::acquire::display::ImageDisplay::GetAppliedShift</b>
|
||||
* \since 2.4.0
|
||||
*/
|
||||
void SetShift(
|
||||
/// [in] The shift value to apply to the displayed images. The maximum value for
|
||||
/// this function is 8, the minimum 0. Values out of this range will be ignored.
|
||||
/// It is \b NOT possible to shift pixel data in such a way that less than 8 bits contain valid
|
||||
/// data, thus e.g. a shift value of 2 applied to 8 bit mono data will be ignored.
|
||||
int shift )
|
||||
{
|
||||
mvDispSetShift( pDisp_, shift );
|
||||
}
|
||||
/// \brief Returns the current shift value that has been applied to the last image that has been displayed.
|
||||
/**
|
||||
* This function returns the shift value that has been applied to the last image that has been displayed.
|
||||
* See \b mvIMPACT::acquire::display::ImageDisplay::SetShift for a detailed explanation about the display behaviour when applying custom shift values.
|
||||
*
|
||||
* \sa
|
||||
* <b>mvIMPACT::acquire::display::ImageDisplay::SetShift,<br>
|
||||
* mvIMPACT::acquire::display::ImageDisplay::GetShift</b>
|
||||
* \since 2.4.0
|
||||
* \return The current shift value that has been applied to the last image that has been displayed.
|
||||
*/
|
||||
int GetAppliedShift( void ) const
|
||||
{
|
||||
return mvDispGetAppliedShift( pDisp_ );
|
||||
}
|
||||
/// \brief Returns the last error and clears it.
|
||||
/**
|
||||
* If an error has occurred it will not be overwritten by subsequent
|
||||
* errors till the error is queried and cleared. After calling this
|
||||
* function a second call would return \b mvIMPACT::acquire::display::IDE_NoError until another error
|
||||
* occurs.
|
||||
*
|
||||
* \return The last error
|
||||
*/
|
||||
int GetLastError( void ) const
|
||||
{
|
||||
return mvDispGetError( pDisp_ );
|
||||
}
|
||||
/// \brief Returns the current window handle associated with the display object.
|
||||
/**
|
||||
* Returns the current window handle associated with the display object.
|
||||
* \return The current window handle associated with the display object.
|
||||
*/
|
||||
WindowHandle GetWindowHandle( void ) const
|
||||
{
|
||||
return mvDispGetWindowHandle( pDisp_ );
|
||||
}
|
||||
/// \brief Assigns a new destination window handle to a display object.
|
||||
void SetWindowHandle(
|
||||
/// [in] The handle of the new destination window.
|
||||
WindowHandle hwnd )
|
||||
{
|
||||
mvDispSetWindowHandle( pDisp_, hwnd );
|
||||
}
|
||||
/// \brief Associates a brush to be used for painting the background within the client area.
|
||||
/**
|
||||
* See \b mvDispInit() for a detailed description on which regions will be painted using
|
||||
* the background brush.
|
||||
*
|
||||
* \warning This only stores the handle to the brush object, not the actual brush, so
|
||||
* as long as this handle is set and the display object is used, the referenced
|
||||
* brush must \b NOT be deleted again.
|
||||
*/
|
||||
void SetBackgroundBrush(
|
||||
/// [in] Handle to the brush to be used to paint the background.
|
||||
/// This brush then will be used to paint the regions of the rectangle
|
||||
/// used for drawing that will not painted with the image itself.
|
||||
BrushHandle hBrush )
|
||||
{
|
||||
mvDispSetBackgroundBrush( pDisp_, hBrush );
|
||||
}
|
||||
/// \brief Defines the key color for the DirectDraw® overlay
|
||||
void SetDDrawOverlayKeyColor(
|
||||
/// [in] The key color to be used for the DirectDraw® overlay.
|
||||
ColorValue keyColor )
|
||||
{
|
||||
mvDispSetDDrawOverlayKeyColor( pDisp_, keyColor );
|
||||
}
|
||||
#ifndef WRAP_ANY
|
||||
/// \brief Installs an overlay callback function.
|
||||
/**
|
||||
* This function will be called when operated in \b mvIMPACT::acquire::display::DM_Default mode
|
||||
* and can be used to draw a user defined overlay on top of the image before it
|
||||
* is displayed.
|
||||
*/
|
||||
void SetOverlayCallbackFunction(
|
||||
/// [in] The address of the function to be called for a user
|
||||
/// defined overlay
|
||||
TImageDisplayOverlayFunction fctOverlay,
|
||||
/// [in] A pointer to a user defined parameter
|
||||
void* pUserParam )
|
||||
{
|
||||
mvDispSetOverlayCallbackFunction( pDisp_, fctOverlay, pUserParam );
|
||||
}
|
||||
#endif // #ifndef WRAP_ANY
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \brief A class that can be used to display images in a window.
|
||||
/**
|
||||
* Every instance of this class will create and display its own independent window.
|
||||
* Internally it uses an instance of <b>mvIMPACT::acquire::display::ImageDisplay</b>
|
||||
* to display image data. The internal display object can be accessed by calling
|
||||
* <b>mvIMPACT::acquire::display::ImageDisplayWindow::GetImageDisplay()</b>.
|
||||
*/
|
||||
class ImageDisplayWindow
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
HDISP hDisp_;
|
||||
ImageDisplay imageDisplay_;
|
||||
|
||||
ImageDisplayWindow( const ImageDisplayWindow& ); // do not allow copy constructor
|
||||
ImageDisplayWindow& operator=( const ImageDisplayWindow& ); // do not allow assignments
|
||||
public:
|
||||
/// \brief Creates a new window that can be used to display image data and displays it.
|
||||
/**
|
||||
* This is an example of how to use the GetImageDisplay class.
|
||||
* More details about this example.
|
||||
*/
|
||||
explicit ImageDisplayWindow(
|
||||
/// [in] The title of the window (will be displayed in the windows title bar).
|
||||
const std::string& title ) : hDisp_( 0 )
|
||||
{
|
||||
hDisp_ = mvDispWindowCreate( title.c_str() );
|
||||
mvDispWindowShow( hDisp_ );
|
||||
imageDisplay_.pDisp_ = mvDispWindowGetDisplayHandle( hDisp_ );
|
||||
}
|
||||
/// \brief destroys the display window and frees resources.
|
||||
~ImageDisplayWindow()
|
||||
{
|
||||
mvDispWindowDestroy( hDisp_ );
|
||||
hDisp_ = 0;
|
||||
}
|
||||
/// \brief Returns a reference to the actual display object associated with this window.
|
||||
ImageDisplay& GetImageDisplay( void )
|
||||
{
|
||||
return imageDisplay_;
|
||||
}
|
||||
/// \brief Defines the refresh time in ms
|
||||
/**
|
||||
* This function can be used to define a refresh period that - when elapsed -
|
||||
* will automatically repaint the window.
|
||||
*/
|
||||
void SetRefreshTime(
|
||||
/// [in] The refresh period for the window in ms. Passing \a 0 will
|
||||
/// disable the automatic repaint behaviour.
|
||||
int time_ms )
|
||||
{
|
||||
mvDispWindowSetRefreshTime( hDisp_, time_ms );
|
||||
}
|
||||
#ifndef WRAP_ANY
|
||||
/// \brief Installs a callback to handle the window messages.
|
||||
/**
|
||||
* \sa
|
||||
* <b>mvIMPACT::acquire::display::ImageDisplayWindow::GetMessageHandler()</b>
|
||||
*/
|
||||
void SetMessageHandler(
|
||||
/// [in] Pointer to a function which is called by the windows
|
||||
/// procedure before the display update is done.
|
||||
/// If zero is passed here even the internal default handler
|
||||
/// will be disabled and \a WM_SIZE and \a WM_LBUTTONDBLCLK will no longer
|
||||
/// be handled internally.
|
||||
TPreProcessMessage handler )
|
||||
{
|
||||
mvDispWindowSetMessageHandler( hDisp_, handler );
|
||||
}
|
||||
/// \brief Returns the current message handler for this window.
|
||||
/**
|
||||
* \sa
|
||||
* <b>mvIMPACT::acquire::display::ImageDisplayWindow::SetMessageHandler()</b>
|
||||
* \return The current message handler for this window.
|
||||
*/
|
||||
TPreProcessMessage GetMessageHandler( void ) const
|
||||
{
|
||||
return mvDispWindowGetMessageHandler( hDisp_ );
|
||||
}
|
||||
#endif // #ifndef WRAP_ANY // The concept of callback functions as used here is rather C/C++ specific.
|
||||
};
|
||||
|
||||
/// @}
|
||||
|
||||
} // namespace display
|
||||
} // namespace acquire
|
||||
} // namespace mvIMPACT
|
||||
|
||||
#if !defined(DOXYGEN_SHOULD_SKIP_THIS) && !defined(WRAP_ANY)
|
||||
# ifndef MVIMPACT_USE_NAMESPACES
|
||||
using namespace mvIMPACT::acquire::display;
|
||||
# endif // #ifndef MVIMPACT_USE_NAMESPACES
|
||||
#endif // #if !defined(DOXYGEN_SHOULD_SKIP_THIS) && !defined(WRAP_ANY)
|
||||
|
||||
#endif //MVIMPACT_ACQUIRE_DISPLAY_H_
|
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue