mirror of
https://github.com/loginov-dmitry/multithread.git
synced 2025-02-20 07:58:22 +02:00
добавлен пример ExWaitWindow
This commit is contained in:
parent
bfd890e424
commit
bcdcb1d8e2
16
ExWaitWindow/D10.4/WaitWindowEx10_4.dpr
Normal file
16
ExWaitWindow/D10.4/WaitWindowEx10_4.dpr
Normal file
@ -0,0 +1,16 @@
|
||||
program WaitWindowEx10_4;
|
||||
|
||||
uses
|
||||
Forms,
|
||||
MainFrm in '..\MainFrm.pas' {MainForm},
|
||||
WaitFrm in '..\WaitFrm.pas' {WaitForm},
|
||||
TimeIntervals in '..\..\CommonUtils\TimeIntervals.pas';
|
||||
|
||||
{$R *.res}
|
||||
|
||||
begin
|
||||
Application.Initialize;
|
||||
Application.MainFormOnTaskbar := True;
|
||||
Application.CreateForm(TMainForm, MainForm);
|
||||
Application.Run;
|
||||
end.
|
957
ExWaitWindow/D10.4/WaitWindowEx10_4.dproj
Normal file
957
ExWaitWindow/D10.4/WaitWindowEx10_4.dproj
Normal file
@ -0,0 +1,957 @@
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<ProjectGuid>{ec9046a0-8814-4b41-9c07-4315c8b50e49}</ProjectGuid>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>
|
||||
<DCC_DependencyCheckOutputName>WaitWindowEx10_4.exe</DCC_DependencyCheckOutputName>
|
||||
<MainSource>WaitWindowEx10_4.dpr</MainSource>
|
||||
<FrameworkType>VCL</FrameworkType>
|
||||
<ProjectVersion>19.1</ProjectVersion>
|
||||
<Base>True</Base>
|
||||
<Config Condition="'$(Config)'==''">Debug</Config>
|
||||
<Platform Condition="'$(Platform)'==''">Win32</Platform>
|
||||
<TargetedPlatforms>32897</TargetedPlatforms>
|
||||
<AppType>Application</AppType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="('$(Platform)'=='Android64' and '$(Base)'=='true') or '$(Base_Android64)'!=''">
|
||||
<Base_Android64>true</Base_Android64>
|
||||
<CfgParent>Base</CfgParent>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
|
||||
<Base_Win32>true</Base_Win32>
|
||||
<CfgParent>Base</CfgParent>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''">
|
||||
<Base_Win64>true</Base_Win64>
|
||||
<CfgParent>Base</CfgParent>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
|
||||
<Cfg_1>true</Cfg_1>
|
||||
<CfgParent>Base</CfgParent>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win32)'!=''">
|
||||
<Cfg_1_Win32>true</Cfg_1_Win32>
|
||||
<CfgParent>Cfg_1</CfgParent>
|
||||
<Cfg_1>true</Cfg_1>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
|
||||
<Cfg_2>true</Cfg_2>
|
||||
<CfgParent>Base</CfgParent>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="('$(Platform)'=='Android64' and '$(Cfg_2)'=='true') or '$(Cfg_2_Android64)'!=''">
|
||||
<Cfg_2_Android64>true</Cfg_2_Android64>
|
||||
<CfgParent>Cfg_2</CfgParent>
|
||||
<Cfg_2>true</Cfg_2>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''">
|
||||
<Cfg_2_Win32>true</Cfg_2_Win32>
|
||||
<CfgParent>Cfg_2</CfgParent>
|
||||
<Cfg_2>true</Cfg_2>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Base)'!=''">
|
||||
<SanitizedProjectName>WaitWindowEx10_4</SanitizedProjectName>
|
||||
<DCC_Namespace>Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace)</DCC_Namespace>
|
||||
<VerInfo_Locale>1049</VerInfo_Locale>
|
||||
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Base_Android64)'!=''">
|
||||
<EnabledSysJars>android-support-v4.dex.jar;cloud-messaging.dex.jar;com-google-android-gms.play-services-ads-base.17.2.0.dex.jar;com-google-android-gms.play-services-ads-identifier.16.0.0.dex.jar;com-google-android-gms.play-services-ads-lite.17.2.0.dex.jar;com-google-android-gms.play-services-ads.17.2.0.dex.jar;com-google-android-gms.play-services-analytics-impl.16.0.8.dex.jar;com-google-android-gms.play-services-analytics.16.0.8.dex.jar;com-google-android-gms.play-services-base.16.0.1.dex.jar;com-google-android-gms.play-services-basement.16.2.0.dex.jar;com-google-android-gms.play-services-gass.17.2.0.dex.jar;com-google-android-gms.play-services-identity.16.0.0.dex.jar;com-google-android-gms.play-services-maps.16.1.0.dex.jar;com-google-android-gms.play-services-measurement-base.16.4.0.dex.jar;com-google-android-gms.play-services-measurement-sdk-api.16.4.0.dex.jar;com-google-android-gms.play-services-stats.16.0.1.dex.jar;com-google-android-gms.play-services-tagmanager-v4-impl.16.0.8.dex.jar;com-google-android-gms.play-services-tasks.16.0.1.dex.jar;com-google-android-gms.play-services-wallet.16.0.1.dex.jar;com-google-firebase.firebase-analytics.16.4.0.dex.jar;com-google-firebase.firebase-common.16.1.0.dex.jar;com-google-firebase.firebase-iid-interop.16.0.1.dex.jar;com-google-firebase.firebase-iid.17.1.1.dex.jar;com-google-firebase.firebase-measurement-connector.17.0.1.dex.jar;com-google-firebase.firebase-messaging.17.5.0.dex.jar;fmx.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar</EnabledSysJars>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Base_Win32)'!=''">
|
||||
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
|
||||
<BT_BuildType>Debug</BT_BuildType>
|
||||
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
|
||||
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)</VerInfo_Keys>
|
||||
<VerInfo_Locale>1033</VerInfo_Locale>
|
||||
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
|
||||
<Icon_MainIcon>WaitWindowEx10_4_Icon.ico</Icon_MainIcon>
|
||||
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
|
||||
<UWP_DelphiLogo44>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png</UWP_DelphiLogo44>
|
||||
<UWP_DelphiLogo150>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png</UWP_DelphiLogo150>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Base_Win64)'!=''">
|
||||
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
|
||||
<Icon_MainIcon>WaitWindowEx10_4_Icon.ico</Icon_MainIcon>
|
||||
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
|
||||
<UWP_DelphiLogo44>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png</UWP_DelphiLogo44>
|
||||
<UWP_DelphiLogo150>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png</UWP_DelphiLogo150>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Cfg_1)'!=''">
|
||||
<Version>7.0</Version>
|
||||
<DCC_DebugInformation>0</DCC_DebugInformation>
|
||||
<DCC_LocalDebugSymbols>False</DCC_LocalDebugSymbols>
|
||||
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
|
||||
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
|
||||
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
|
||||
<AppDPIAwarenessMode>PerMonitorV2</AppDPIAwarenessMode>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Cfg_2)'!=''">
|
||||
<Version>7.0</Version>
|
||||
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Cfg_2_Android64)'!=''">
|
||||
<BT_BuildType>Debug</BT_BuildType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
|
||||
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
|
||||
<AppDPIAwarenessMode>PerMonitorV2</AppDPIAwarenessMode>
|
||||
</PropertyGroup>
|
||||
<ProjectExtensions>
|
||||
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
|
||||
<Borland.ProjectType/>
|
||||
<BorlandProject>
|
||||
<Delphi.Personality>
|
||||
<Parameters>
|
||||
<Parameters Name="UseLauncher">False</Parameters>
|
||||
<Parameters Name="LoadAllSymbols">True</Parameters>
|
||||
<Parameters Name="LoadUnspecifiedSymbols">False</Parameters>
|
||||
</Parameters>
|
||||
<VersionInfo>
|
||||
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
|
||||
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
|
||||
<VersionInfo Name="MajorVer">1</VersionInfo>
|
||||
<VersionInfo Name="MinorVer">0</VersionInfo>
|
||||
<VersionInfo Name="Release">0</VersionInfo>
|
||||
<VersionInfo Name="Build">0</VersionInfo>
|
||||
<VersionInfo Name="Debug">False</VersionInfo>
|
||||
<VersionInfo Name="PreRelease">False</VersionInfo>
|
||||
<VersionInfo Name="Special">False</VersionInfo>
|
||||
<VersionInfo Name="Private">False</VersionInfo>
|
||||
<VersionInfo Name="DLL">False</VersionInfo>
|
||||
<VersionInfo Name="Locale">1049</VersionInfo>
|
||||
<VersionInfo Name="CodePage">1251</VersionInfo>
|
||||
</VersionInfo>
|
||||
<VersionInfoKeys>
|
||||
<VersionInfoKeys Name="CompanyName"/>
|
||||
<VersionInfoKeys Name="FileDescription"/>
|
||||
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
|
||||
<VersionInfoKeys Name="InternalName"/>
|
||||
<VersionInfoKeys Name="LegalCopyright"/>
|
||||
<VersionInfoKeys Name="LegalTrademarks"/>
|
||||
<VersionInfoKeys Name="OriginalFilename"/>
|
||||
<VersionInfoKeys Name="ProductName"/>
|
||||
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
|
||||
<VersionInfoKeys Name="Comments"/>
|
||||
</VersionInfoKeys>
|
||||
<Source>
|
||||
<Source Name="MainSource">WaitWindowEx10_4.dpr</Source>
|
||||
</Source>
|
||||
</Delphi.Personality>
|
||||
<Platforms>
|
||||
<Platform value="Android64">True</Platform>
|
||||
<Platform value="Linux64">True</Platform>
|
||||
<Platform value="Win32">True</Platform>
|
||||
<Platform value="Win64">False</Platform>
|
||||
</Platforms>
|
||||
<Deployment Version="3">
|
||||
<DeployFile LocalName="WaitWindowEx10_4.exe" Configuration="Debug" Class="ProjectOutput">
|
||||
<Platform Name="Win32">
|
||||
<RemoteName>WaitWindowEx10_4.exe</RemoteName>
|
||||
<Overwrite>true</Overwrite>
|
||||
</Platform>
|
||||
</DeployFile>
|
||||
<DeployClass Name="AdditionalDebugSymbols">
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="OSX32">
|
||||
<RemoteDir>Contents\MacOS</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="AndroidClassesDexFile">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>classes</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>classes</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="AndroidFileProvider">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\xml</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\xml</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="AndroidGDBServer">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="AndroidLibnativeArmeabiFile">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>library\lib\armeabi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>library\lib\armeabi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="AndroidLibnativeArmeabiv7aFile">
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="AndroidLibnativeMipsFile">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>library\lib\mips</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>library\lib\mips</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="AndroidServiceOutput">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>library\lib\arm64-v8a</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="AndroidServiceOutput_Android32">
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="AndroidSplashImageDef">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\drawable</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="AndroidSplashStyles">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\values</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\values</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="AndroidSplashStylesV21">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\values-v21</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\values-v21</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_Colors">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\values</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\values</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_DefaultAppIcon">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\drawable</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_LauncherIcon144">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_LauncherIcon36">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-ldpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\drawable-ldpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_LauncherIcon48">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-mdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\drawable-mdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_LauncherIcon72">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-hdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\drawable-hdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_LauncherIcon96">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-xhdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\drawable-xhdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_NotificationIcon24">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-mdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\drawable-mdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_NotificationIcon36">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-hdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\drawable-hdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_NotificationIcon48">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-xhdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\drawable-xhdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_NotificationIcon72">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_NotificationIcon96">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_SplashImage426">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-small</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\drawable-small</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_SplashImage470">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-normal</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\drawable-normal</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_SplashImage640">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-large</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\drawable-large</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_SplashImage960">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-xlarge</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\drawable-xlarge</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_Strings">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\values</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\values</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="DebugSymbols">
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="OSX32">
|
||||
<RemoteDir>Contents\MacOS</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="DependencyFramework">
|
||||
<Platform Name="OSX32">
|
||||
<RemoteDir>Contents\MacOS</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.framework</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="OSX64">
|
||||
<RemoteDir>Contents\MacOS</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.framework</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="DependencyModule">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="OSX32">
|
||||
<RemoteDir>Contents\MacOS</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="OSX64">
|
||||
<RemoteDir>Contents\MacOS</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
<Extensions>.dll;.bpl</Extensions>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Required="true" Name="DependencyPackage">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="OSX32">
|
||||
<RemoteDir>Contents\MacOS</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="OSX64">
|
||||
<RemoteDir>Contents\MacOS</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
<Extensions>.bpl</Extensions>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="File">
|
||||
<Platform Name="Android">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
<Platform Name="OSX32">
|
||||
<RemoteDir>Contents\Resources\StartUp\</RemoteDir>
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
<Platform Name="OSX64">
|
||||
<RemoteDir>Contents\Resources\StartUp\</RemoteDir>
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iOS_AppStore1024">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPad_AppIcon152">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPad_AppIcon167">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPad_Launch2x">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPad_LaunchDark2x">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPad_Notification40">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPad_Setting58">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPad_SpotLight80">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_AppIcon120">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_AppIcon180">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_Launch2x">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_Launch3x">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_LaunchDark2x">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_LaunchDark3x">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_Notification40">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_Notification60">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_Setting58">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_Setting87">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_Spotlight120">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_Spotlight80">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectAndroidManifest">
|
||||
<Platform Name="Android">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectiOSDeviceDebug">
|
||||
<Platform Name="iOSDevice32">
|
||||
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectiOSEntitlements">
|
||||
<Platform Name="iOSDevice32">
|
||||
<RemoteDir>..\</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectiOSInfoPList">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectiOSLaunchScreen">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen</RemoteDir>
|
||||
<Operation>64</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen</RemoteDir>
|
||||
<Operation>64</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectiOSResource">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectOSXDebug">
|
||||
<Platform Name="OSX64">
|
||||
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectOSXEntitlements">
|
||||
<Platform Name="OSX32">
|
||||
<RemoteDir>..\</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="OSX64">
|
||||
<RemoteDir>..\</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectOSXInfoPList">
|
||||
<Platform Name="OSX32">
|
||||
<RemoteDir>Contents</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="OSX64">
|
||||
<RemoteDir>Contents</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectOSXResource">
|
||||
<Platform Name="OSX32">
|
||||
<RemoteDir>Contents\Resources</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="OSX64">
|
||||
<RemoteDir>Contents\Resources</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Required="true" Name="ProjectOutput">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>library\lib\arm64-v8a</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Linux64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="OSX32">
|
||||
<RemoteDir>Contents\MacOS</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="OSX64">
|
||||
<RemoteDir>Contents\MacOS</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectOutput_Android32">
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectUWPManifest">
|
||||
<Platform Name="Win32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Win64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="UWP_DelphiLogo150">
|
||||
<Platform Name="Win32">
|
||||
<RemoteDir>Assets</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Win64">
|
||||
<RemoteDir>Assets</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="UWP_DelphiLogo44">
|
||||
<Platform Name="Win32">
|
||||
<RemoteDir>Assets</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Win64">
|
||||
<RemoteDir>Assets</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/>
|
||||
<ProjectRoot Platform="Win64" Name="$(PROJECTNAME)"/>
|
||||
<ProjectRoot Platform="iOSDevice32" Name="$(PROJECTNAME).app"/>
|
||||
<ProjectRoot Platform="Linux64" Name="$(PROJECTNAME)"/>
|
||||
<ProjectRoot Platform="Win32" Name="$(PROJECTNAME)"/>
|
||||
<ProjectRoot Platform="OSX32" Name="$(PROJECTNAME).app"/>
|
||||
<ProjectRoot Platform="Android" Name="$(PROJECTNAME)"/>
|
||||
<ProjectRoot Platform="OSX64" Name="$(PROJECTNAME).app"/>
|
||||
<ProjectRoot Platform="iOSSimulator" Name="$(PROJECTNAME).app"/>
|
||||
<ProjectRoot Platform="Android64" Name="$(PROJECTNAME)"/>
|
||||
</Deployment>
|
||||
</BorlandProject>
|
||||
<ProjectFileVersion>12</ProjectFileVersion>
|
||||
</ProjectExtensions>
|
||||
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets"/>
|
||||
<ItemGroup>
|
||||
<DelphiCompile Include="$(MainSource)">
|
||||
<MainSource>MainSource</MainSource>
|
||||
</DelphiCompile>
|
||||
<DCCReference Include="..\MainFrm.pas">
|
||||
<Form>MainForm</Form>
|
||||
</DCCReference>
|
||||
<DCCReference Include="..\WaitFrm.pas">
|
||||
<Form>WaitForm</Form>
|
||||
</DCCReference>
|
||||
<DCCReference Include="..\..\CommonUtils\TimeIntervals.pas"/>
|
||||
<BuildConfiguration Include="Debug">
|
||||
<Key>Cfg_2</Key>
|
||||
<CfgParent>Base</CfgParent>
|
||||
</BuildConfiguration>
|
||||
<BuildConfiguration Include="Base">
|
||||
<Key>Base</Key>
|
||||
</BuildConfiguration>
|
||||
<BuildConfiguration Include="Release">
|
||||
<Key>Cfg_1</Key>
|
||||
<CfgParent>Base</CfgParent>
|
||||
</BuildConfiguration>
|
||||
</ItemGroup>
|
||||
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
|
||||
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
|
||||
<Import Project="$(MSBuildProjectName).deployproj" Condition="Exists('$(MSBuildProjectName).deployproj')"/>
|
||||
</Project>
|
BIN
ExWaitWindow/D10.4/WaitWindowEx10_4.res
Normal file
BIN
ExWaitWindow/D10.4/WaitWindowEx10_4.res
Normal file
Binary file not shown.
BIN
ExWaitWindow/D10.4/WaitWindowEx10_4_Icon.ico
Normal file
BIN
ExWaitWindow/D10.4/WaitWindowEx10_4_Icon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
123
ExWaitWindow/MainFrm.dfm
Normal file
123
ExWaitWindow/MainFrm.dfm
Normal file
@ -0,0 +1,123 @@
|
||||
object MainForm: TMainForm
|
||||
Left = 0
|
||||
Top = 0
|
||||
Caption =
|
||||
#1055#1088#1080#1084#1077#1088' '#1086#1090#1086#1073#1088#1072#1078#1077#1085#1080#1103' '#1084#1086#1076#1072#1083#1100#1085#1086#1075#1086' '#1086#1082#1085#1072' '#1087#1088#1080' '#1074#1099#1087#1086#1083#1085#1077#1085#1080#1080' '#1086#1087#1077#1088#1072#1094#1080#1080' '#1074' '#1076#1086#1087 +
|
||||
'. '#1087#1086#1090#1086#1082#1077
|
||||
ClientHeight = 440
|
||||
ClientWidth = 592
|
||||
Color = clBtnFace
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -13
|
||||
Font.Name = 'Tahoma'
|
||||
Font.Style = []
|
||||
OldCreateOrder = False
|
||||
OnCreate = FormCreate
|
||||
DesignSize = (
|
||||
592
|
||||
440)
|
||||
PixelsPerInch = 96
|
||||
TextHeight = 16
|
||||
object Label1: TLabel
|
||||
Left = 40
|
||||
Top = 16
|
||||
Width = 504
|
||||
Height = 208
|
||||
Caption =
|
||||
#1042' '#1076#1072#1085#1085#1086#1084' '#1087#1088#1080#1084#1077#1088#1077' '#1076#1077#1084#1086#1085#1089#1090#1088#1080#1088#1091#1077#1090#1089#1103', '#1082#1072#1082' '#1084#1086#1078#1085#1086' '#1074#1099#1087#1086#1083#1085#1080#1090#1100' '#1089#1077#1088#1080#1102' '#1074#1079#1072#1080 +
|
||||
#1084#1086#1089#1074#1103#1079#1072#1085#1085#1099#1093' '#13#10#1076#1083#1080#1090#1077#1083#1100#1085#1099#1093' '#1086#1087#1077#1088#1072#1094#1080#1081' '#1080' '#1087#1088#1080' '#1101#1090#1086#1084' '#1085#1077' '#1073#1083#1086#1082#1080#1088#1086#1074#1072#1090#1100' '#1075#1083#1072#1074 +
|
||||
#1085#1099#1081' '#1087#1086#1090#1086#1082'. '#13#10#1044#1077#1084#1086#1085#1089#1090#1088#1080#1088#1091#1077#1090#1089#1103' '#1101#1084#1091#1083#1103#1094#1080#1103' '#1087#1088#1086#1076#1072#1078#1080' '#1090#1086#1074#1072#1088#1072' '#1087#1086' '#1073#1072#1085#1082#1086#1074#1089#1082 +
|
||||
#1086#1081' '#1082#1072#1088#1090#1077'. '#1054#1085#1072' '#1089#1086#1089#1090#1086#1080#1090' '#13#10#1080#1079' '#1089#1083#1077#1076#1091#1102#1097#1080#1093' '#1076#1077#1081#1089#1090#1074#1080#1081':'#13#10'1) '#1054#1087#1077#1088#1072#1094#1080#1103' '#1089' ' +
|
||||
#1073#1072#1085#1082#1086#1074#1089#1082#1086#1081' '#1082#1072#1088#1090#1086#1081' ('#1091#1087#1088#1072#1074#1083#1077#1085#1080#1077' '#1087#1077#1088#1077#1076#1072#1105#1090#1089#1103' '#1084#1086#1076#1091#1083#1102' '#1073#1072#1085#1082#1086#1074#1089#1082#1086#1075#1086#13#10#1087#1088#1086 +
|
||||
#1094#1077#1089#1089#1080#1085#1075#1072'. '#1054#1087#1077#1088#1072#1094#1080#1103' '#1084#1086#1078#1077#1090' '#1079#1072#1085#1103#1090#1100' '#1085#1077#1089#1082#1086#1083#1100#1082#1086' '#1084#1080#1085#1091#1090').'#13#10'2) '#1060#1080#1082#1089#1072#1094#1080#1103' '#1090 +
|
||||
#1088#1072#1085#1079#1072#1082#1094#1080#1080' '#1074' '#1073#1072#1079#1091' '#1076#1072#1085#1085#1099#1093' ('#1086#1087#1077#1088#1072#1094#1080#1103' '#1084#1086#1078#1077#1090' '#1079#1072#1085#1103#1090#1100' '#1085#1077#1089#1082#1086#1083#1100#1082#1086' '#1089#1077#1082#1091#1085#1076')' +
|
||||
#13#10'3) '#1055#1088#1086#1073#1080#1090#1080#1077' '#1095#1077#1082#1072' '#1085#1072' '#1082#1072#1089#1089#1077' ('#1086#1087#1077#1088#1072#1094#1080#1103' '#1084#1086#1078#1077#1090' '#1079#1072#1085#1103#1090#1100' '#1085#1077#1089#1082#1086#1083#1100#1082#1086' '#1089#1077#1082 +
|
||||
#1091#1085#1076')'#13#10#13#10#1041#1083#1072#1075#1086#1076#1072#1088#1103' '#1090#1086#1084#1091', '#1095#1090#1086' '#1075#1083#1072#1074#1085#1099#1081' '#1087#1086#1090#1086#1082' '#1085#1077' '#1073#1083#1086#1082#1080#1088#1091#1077#1090#1089#1103', '#1087#1088#1086#1075#1088#1072 +
|
||||
#1084#1084#1072' '#1084#1086#1078#1077#1090' '#1074' '#1092#1086#1085#1077#13#10#1074#1099#1087#1086#1083#1085#1103#1090#1100' '#1083#1102#1073#1099#1077' '#1086#1087#1077#1088#1072#1094#1080#1080' ('#1085#1072#1087#1088#1080#1084#1077#1088', '#1089#1080#1085#1093#1088#1086#1085#1080#1079#1072 +
|
||||
#1094#1080#1103' '#1089' '#1076#1088#1091#1075#1086#1081' '#1091#1095#1105#1090#1085#1086#1081' '#1089#1080#1089#1090#1077#1084#1086#1081','#13#10#1088#1077#1079#1077#1088#1074#1080#1088#1086#1074#1072#1085#1080#1077' '#1073#1072#1079#1099' '#1076#1072#1085#1085#1099#1093', '#1086#1087#1088#1086 +
|
||||
#1089' '#1086#1073#1086#1088#1091#1076#1086#1074#1072#1085#1080#1103', '#1086#1090#1086#1073#1088#1072#1078#1077#1085#1080#1077' '#1090#1077#1082#1091#1097#1077#1075#1086#13#10#1074#1088#1077#1084#1077#1085#1080' '#1080' '#1090'.'#1076'.)'
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clBlue
|
||||
Font.Height = -13
|
||||
Font.Name = 'Tahoma'
|
||||
Font.Style = []
|
||||
ParentFont = False
|
||||
end
|
||||
object Label2: TLabel
|
||||
Left = 40
|
||||
Top = 413
|
||||
Width = 117
|
||||
Height = 19
|
||||
Anchors = [akLeft, akBottom]
|
||||
Caption = #1058#1077#1082#1091#1097#1077#1077' '#1074#1088#1077#1084#1103':'
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -16
|
||||
Font.Name = 'Tahoma'
|
||||
Font.Style = []
|
||||
ParentFont = False
|
||||
ExplicitTop = 344
|
||||
end
|
||||
object labCurTime: TLabel
|
||||
Left = 163
|
||||
Top = 413
|
||||
Width = 24
|
||||
Height = 19
|
||||
Anchors = [akLeft, akBottom]
|
||||
Caption = '???'
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -16
|
||||
Font.Name = 'Tahoma'
|
||||
Font.Style = []
|
||||
ParentFont = False
|
||||
ExplicitTop = 344
|
||||
end
|
||||
object Label3: TLabel
|
||||
Left = 200
|
||||
Top = 330
|
||||
Width = 280
|
||||
Height = 16
|
||||
Caption = #1053#1072#1082#1083#1072#1076#1085#1099#1077' '#1088#1072#1089#1093#1086#1076#1099' '#1089#1086#1089#1090#1072#1074#1083#1103#1102#1090' '#1086#1090' 10 '#1076#1086' 30 '#1084#1089
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clBlue
|
||||
Font.Height = -13
|
||||
Font.Name = 'Tahoma'
|
||||
Font.Style = []
|
||||
ParentFont = False
|
||||
end
|
||||
object Button1: TButton
|
||||
Left = 64
|
||||
Top = 248
|
||||
Width = 433
|
||||
Height = 41
|
||||
Caption = #1042#1099#1087#1086#1083#1085#1080#1090#1100' '#1101#1084#1091#1083#1103#1094#1080#1102' '#1087#1088#1086#1076#1072#1078#1080' '#1087#1086' '#1073#1072#1085#1082#1086#1074#1089#1082#1086#1081' '#1082#1072#1088#1090#1077
|
||||
TabOrder = 0
|
||||
OnClick = Button1Click
|
||||
end
|
||||
object Button2: TButton
|
||||
Left = 64
|
||||
Top = 296
|
||||
Width = 433
|
||||
Height = 34
|
||||
Caption = #1048#1079#1084#1077#1088#1077#1085#1080#1077' '#1085#1072#1082#1083#1072#1076#1085#1099#1093' '#1088#1072#1089#1093#1086#1076#1086#1074' '#1085#1072' '#1087#1086#1082#1072#1079' '#1084#1086#1076#1072#1083#1100#1085#1086#1081' '#1092#1086#1088#1084#1099
|
||||
TabOrder = 1
|
||||
OnClick = Button2Click
|
||||
end
|
||||
object Button3: TButton
|
||||
Left = 64
|
||||
Top = 352
|
||||
Width = 433
|
||||
Height = 41
|
||||
Caption = #1044#1077#1084#1086#1085#1089#1090#1088#1072#1094#1080#1103' ProgressBar'
|
||||
TabOrder = 2
|
||||
OnClick = Button3Click
|
||||
end
|
||||
object Timer1: TTimer
|
||||
Interval = 300
|
||||
OnTimer = Timer1Timer
|
||||
Left = 16
|
||||
Top = 248
|
||||
end
|
||||
end
|
204
ExWaitWindow/MainFrm.pas
Normal file
204
ExWaitWindow/MainFrm.pas
Normal file
@ -0,0 +1,204 @@
|
||||
{
|
||||
Copyright (c) 2021, Loginov Dmitry Sergeevich
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER OR CONTRIBUTORS 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.
|
||||
}
|
||||
|
||||
unit MainFrm;
|
||||
|
||||
interface
|
||||
|
||||
{$IF RTLVersion >= 20.00}
|
||||
{$DEFINE D2009PLUS}
|
||||
{$IFEND}
|
||||
|
||||
uses
|
||||
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
|
||||
Dialogs, ExtCtrls, StdCtrls, WaitFrm, TimeIntervals;
|
||||
|
||||
type
|
||||
TMainForm = class(TForm)
|
||||
Label1: TLabel;
|
||||
Label2: TLabel;
|
||||
labCurTime: TLabel;
|
||||
Timer1: TTimer;
|
||||
Button1: TButton;
|
||||
Button2: TButton;
|
||||
Label3: TLabel;
|
||||
Button3: TButton;
|
||||
procedure Timer1Timer(Sender: TObject);
|
||||
procedure Button1Click(Sender: TObject);
|
||||
procedure Button2Click(Sender: TObject);
|
||||
procedure Button3Click(Sender: TObject);
|
||||
procedure FormCreate(Sender: TObject);
|
||||
private
|
||||
function PrintKKMCheck(OperType: Integer; AParams: Variant; var AResParams: Variant;
|
||||
wsi: TWaitStatusInterface): Boolean;
|
||||
{ Private declarations }
|
||||
public
|
||||
{ Public declarations }
|
||||
end;
|
||||
|
||||
function BankOperation(OperType: Integer; AParams: Variant; var AResParams: Variant; wsi: TWaitStatusInterface): Boolean;
|
||||
|
||||
var
|
||||
MainForm: TMainForm;
|
||||
|
||||
implementation
|
||||
|
||||
{$R *.dfm}
|
||||
|
||||
function BankOperation(OperType: Integer; AParams: Variant; var AResParams: Variant; wsi: TWaitStatusInterface): Boolean;
|
||||
begin
|
||||
wsi.StatusLine[1] := 'Вставьте/приложите карту';
|
||||
Sleep(2000);
|
||||
//raise Exception.Create('BankOperation error!');
|
||||
wsi.CheckNeedStop();
|
||||
wsi.StatusLine[1] := 'Введите ПИН-КОД';
|
||||
Sleep(1000);
|
||||
wsi.CheckNeedStop();
|
||||
wsi.StatusLine[2] := '*';
|
||||
Sleep(500);
|
||||
wsi.CheckNeedStop();
|
||||
wsi.StatusLine[2] := '**';
|
||||
Sleep(500);
|
||||
wsi.CheckNeedStop();
|
||||
wsi.StatusLine[2] := '***';
|
||||
Sleep(500);
|
||||
wsi.CheckNeedStop();
|
||||
wsi.StatusLine[2] := '****';
|
||||
Sleep(500);
|
||||
wsi.CheckNeedStop();
|
||||
wsi.StatusLine[2] := '';
|
||||
wsi.StatusLine[1] := 'Выполняется соединение с банком...';
|
||||
Sleep(2000);
|
||||
wsi.StatusLine[1] := 'Операция проведена успешно!';
|
||||
Sleep(1000);
|
||||
wsi.StatusLine[1] := 'Извлеките карту';
|
||||
Sleep(1000);
|
||||
AResParams := VarArrayOf(['VISA****8077']);
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
function SaveTransactionInDB(OperType: Integer; AParams: Variant; var AResParams: Variant; wsi: TWaitStatusInterface): Boolean;
|
||||
var
|
||||
TovarName, CardNum: string;
|
||||
Summa: Currency;
|
||||
begin
|
||||
TovarName := AParams[0];
|
||||
Summa := AParams[1];
|
||||
CardNum := AParams[3];
|
||||
wsi.StatusLine[1] := Format('Товар: %s; %fр.; Карта: %s', [TovarName, Summa, CardNum]);
|
||||
Sleep(2000);
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
function FastOperation(OperType: Integer; AParams: Variant; var AResParams: Variant; wsi: TWaitStatusInterface): Boolean;
|
||||
begin
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
procedure TMainForm.Button2Click(Sender: TObject);
|
||||
var
|
||||
ti: TTimeInterval;
|
||||
ResParams: Variant;
|
||||
begin
|
||||
ti.Start;
|
||||
{$IFDEF D2009PLUS}
|
||||
// Демонстрация использования анонимной функции
|
||||
DoOperationInThread(Self, OPERATION_TYPE_NONE, 'Быстрая операция', Null,
|
||||
function (OperType: Integer; AParams: Variant; var AResParams: Variant; wsi: TWaitStatusInterface): Boolean
|
||||
begin
|
||||
Result := True;
|
||||
end, NOT_SHOW_STOP_BTN, ResParams);
|
||||
{$ELSE}
|
||||
DoOperationInThread(Self, OPERATION_TYPE_NONE, 'Быстрая операция', Null, FastOperation, NOT_SHOW_STOP_BTN, ResParams);
|
||||
{$ENDIF}
|
||||
ShowMessageFmt('Время выполнения операции: %d мс', [ti.ElapsedMilliseconds]);
|
||||
end;
|
||||
|
||||
function ProgressOperation(OperType: Integer; AParams: Variant; var AResParams: Variant; wsi: TWaitStatusInterface): Boolean;
|
||||
var
|
||||
I: Integer;
|
||||
begin
|
||||
wsi.SetProgressMinMax(100, 600);
|
||||
for I := 100 to 600 do
|
||||
begin
|
||||
wsi.StatusLine[1] := 'Текущее значение: ' + IntToStr(I);
|
||||
wsi.ProgressPosition := I;
|
||||
Sleep(10);
|
||||
wsi.CheckNeedStop;
|
||||
end;
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
procedure TMainForm.Button3Click(Sender: TObject);
|
||||
var
|
||||
ResParams: Variant;
|
||||
begin
|
||||
DoOperationInThread(Self, OPERATION_TYPE_NONE, 'Длительные вычисления', Null, ProgressOperation, NEED_SHOW_STOP_BTN, ResParams);
|
||||
end;
|
||||
|
||||
procedure TMainForm.FormCreate(Sender: TObject);
|
||||
begin
|
||||
ReportMemoryLeaksOnShutdown := True;
|
||||
end;
|
||||
|
||||
function TMainForm.PrintKKMCheck(OperType: Integer; AParams: Variant; var AResParams: Variant; wsi: TWaitStatusInterface): Boolean;
|
||||
var
|
||||
TovarName, CardNum: string;
|
||||
Summa: Currency;
|
||||
begin
|
||||
TovarName := AParams[0];
|
||||
Summa := AParams[1];
|
||||
CardNum := AParams[3];
|
||||
wsi.StatusLine[1] := Format('Товар: %s; %fр.; Карта: %s', [TovarName, Summa, CardNum]);
|
||||
Sleep(2000);
|
||||
wsi.OperationName := 'Закрытие чека ККМ';
|
||||
Sleep(1000);
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
procedure TMainForm.Button1Click(Sender: TObject);
|
||||
var
|
||||
Summa: Currency;
|
||||
ResParams: Variant;
|
||||
CardNum, TovarName: string;
|
||||
PayType: string;
|
||||
begin
|
||||
TovarName := 'Молоко';
|
||||
Summa := 51.23;
|
||||
PayType := 'ByCard';
|
||||
if DoOperationInThread(Self, OPERATION_TYPE_NONE, 'Операция с банковской картой', VarArrayOf([Summa]), BankOperation, NEED_SHOW_STOP_BTN, ResParams) then
|
||||
begin
|
||||
CardNum := ResParams[0];
|
||||
DoOperationInThread(Self, OPERATION_TYPE_NONE, 'Сохранение транзакции в БД', VarArrayOf([TovarName, Summa, PayType, CardNum]), SaveTransactionInDB, NOT_SHOW_STOP_BTN, ResParams);
|
||||
DoOperationInThread(Self, OPERATION_TYPE_NONE, 'Печать чека ККМ', VarArrayOf([TovarName, Summa, PayType, CardNum]), PrintKKMCheck, NOT_SHOW_STOP_BTN, ResParams);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TMainForm.Timer1Timer(Sender: TObject);
|
||||
begin
|
||||
labCurTime.Caption := FormatDateTime('dd.mm.yyyy hh:nn:ss', Now);
|
||||
end;
|
||||
|
||||
end.
|
137
ExWaitWindow/WaitFrm.dfm
Normal file
137
ExWaitWindow/WaitFrm.dfm
Normal file
@ -0,0 +1,137 @@
|
||||
object WaitForm: TWaitForm
|
||||
Left = 0
|
||||
Top = 0
|
||||
BorderIcons = []
|
||||
BorderStyle = bsDialog
|
||||
Caption = #1042#1099#1087#1086#1083#1085#1103#1077#1090#1089#1103' '#1076#1083#1080#1090#1077#1083#1100#1085#1072#1103' '#1086#1087#1077#1088#1072#1094#1080#1103
|
||||
ClientHeight = 237
|
||||
ClientWidth = 391
|
||||
Color = clBtnFace
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -16
|
||||
Font.Name = 'Tahoma'
|
||||
Font.Style = []
|
||||
OldCreateOrder = False
|
||||
Position = poScreenCenter
|
||||
OnCloseQuery = FormCloseQuery
|
||||
OnShow = FormShow
|
||||
DesignSize = (
|
||||
391
|
||||
237)
|
||||
PixelsPerInch = 96
|
||||
TextHeight = 19
|
||||
object Label1: TLabel
|
||||
Left = 21
|
||||
Top = 10
|
||||
Width = 353
|
||||
Height = 23
|
||||
Caption = #1042#1099#1087#1086#1083#1085#1103#1077#1090#1089#1103' '#1076#1083#1080#1090#1077#1083#1100#1085#1072#1103' '#1086#1087#1077#1088#1072#1094#1080#1103
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -19
|
||||
Font.Name = 'Tahoma'
|
||||
Font.Style = [fsBold]
|
||||
ParentFont = False
|
||||
end
|
||||
object labOperationName: TLabel
|
||||
Left = 8
|
||||
Top = 57
|
||||
Width = 248
|
||||
Height = 19
|
||||
Alignment = taCenter
|
||||
Caption = #1053#1072#1080#1084#1077#1085#1086#1074#1072#1085#1080#1077' '#1090#1077#1082#1091#1097#1077#1081' '#1086#1087#1077#1088#1072#1094#1080#1080
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -16
|
||||
Font.Name = 'Tahoma'
|
||||
Font.Style = []
|
||||
ParentFont = False
|
||||
end
|
||||
object Label3: TLabel
|
||||
Left = 159
|
||||
Top = 191
|
||||
Width = 83
|
||||
Height = 23
|
||||
Anchors = [akLeft, akBottom]
|
||||
Caption = #1046#1076#1080#1090#1077'...'
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clBlue
|
||||
Font.Height = -19
|
||||
Font.Name = 'Tahoma'
|
||||
Font.Style = [fsBold]
|
||||
ParentFont = False
|
||||
ExplicitTop = 148
|
||||
end
|
||||
object Label4: TLabel
|
||||
Left = 8
|
||||
Top = 216
|
||||
Width = 105
|
||||
Height = 16
|
||||
Anchors = [akLeft, akBottom]
|
||||
Caption = #1055#1088#1086#1096#1083#1086' '#1074#1088#1077#1084#1077#1085#1080':'
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -13
|
||||
Font.Name = 'Tahoma'
|
||||
Font.Style = []
|
||||
ParentFont = False
|
||||
ExplicitTop = 173
|
||||
end
|
||||
object lbTime: TLabel
|
||||
Left = 119
|
||||
Top = 217
|
||||
Width = 33
|
||||
Height = 16
|
||||
Anchors = [akLeft, akBottom]
|
||||
Caption = '00:00'
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -13
|
||||
Font.Name = 'Tahoma'
|
||||
Font.Style = []
|
||||
ParentFont = False
|
||||
ExplicitTop = 173
|
||||
end
|
||||
object btnStop: TSpeedButton
|
||||
Left = 296
|
||||
Top = 208
|
||||
Width = 82
|
||||
Height = 25
|
||||
Anchors = [akLeft, akBottom]
|
||||
Caption = #1054#1090#1084#1077#1085#1072
|
||||
Visible = False
|
||||
OnClick = btnStopClick
|
||||
ExplicitTop = 165
|
||||
end
|
||||
object labWaitStatus: TLabel
|
||||
Left = 8
|
||||
Top = 86
|
||||
Width = 375
|
||||
Height = 76
|
||||
Alignment = taCenter
|
||||
AutoSize = False
|
||||
Caption = #1057#1090#1072#1090#1091#1089' 1'#13#10#1057#1090#1072#1090#1091#1089' 2'#13#10#1057#1090#1072#1090#1091#1089' 3'#13#10#1057#1090#1072#1090#1091#1089' 4'
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -16
|
||||
Font.Name = 'Tahoma'
|
||||
Font.Style = []
|
||||
ParentFont = False
|
||||
end
|
||||
object ProgressBar1: TProgressBar
|
||||
Left = 32
|
||||
Top = 171
|
||||
Width = 321
|
||||
Height = 17
|
||||
Smooth = True
|
||||
TabOrder = 0
|
||||
Visible = False
|
||||
end
|
||||
object Timer1: TTimer
|
||||
Interval = 200
|
||||
OnTimer = Timer1Timer
|
||||
Left = 16
|
||||
Top = 40
|
||||
end
|
||||
end
|
432
ExWaitWindow/WaitFrm.pas
Normal file
432
ExWaitWindow/WaitFrm.pas
Normal file
@ -0,0 +1,432 @@
|
||||
{
|
||||
Copyright (c) 2021, Loginov Dmitry Sergeevich
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER OR CONTRIBUTORS 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.
|
||||
}
|
||||
|
||||
unit WaitFrm;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
|
||||
Dialogs, StdCtrls, ActiveX, ExtCtrls, Buttons, SyncObjs, ComCtrls;
|
||||
|
||||
{$IF RTLVersion >= 20.00}
|
||||
{$DEFINE D2009PLUS}
|
||||
{$IFEND}
|
||||
|
||||
const
|
||||
NEED_SHOW_STOP_BTN = True;
|
||||
NOT_SHOW_STOP_BTN = False;
|
||||
OPERATION_TYPE_NONE = 0;
|
||||
|
||||
type
|
||||
{Интерфейс можно вынести (при необходимости) в отдельный файл. Интерфейсную
|
||||
ссылку можно передавать в DLL. IID не указан, т.к. технология COM здесь не
|
||||
используется }
|
||||
TWaitStatusInterface = interface
|
||||
// private
|
||||
function GetOperationName: string;
|
||||
procedure SetOperationName(const Value: string);
|
||||
function GetStatusText: string;
|
||||
procedure SetStatusText(const Value: string);
|
||||
function GetNeedStop: Boolean;
|
||||
procedure SetNeedStop(const Value: Boolean);
|
||||
function GetStatusLine(LineNum: Integer): string;
|
||||
procedure SetStatusLine(LineNum: Integer; const Value: string);
|
||||
procedure SetProgressPosition(Value: Double);
|
||||
function GetProgressPosition: Double;
|
||||
|
||||
// public
|
||||
property OperationName: string read GetOperationName write SetOperationName;
|
||||
property StatusText: string read GetStatusText write SetStatusText;
|
||||
property NeedStop: Boolean read GetNeedStop write SetNeedStop;
|
||||
property ProgressPosition: Double read GetProgressPosition write SetProgressPosition;
|
||||
property StatusLine[LineNum: Integer]: string read GetStatusLine write SetStatusLine;
|
||||
procedure ClearStatusText;
|
||||
procedure CheckNeedStop;
|
||||
procedure SetProgressMinMax(AMin, AMax: Double);
|
||||
function GetProgressMin: Integer;
|
||||
function GetProgressMax: Integer;
|
||||
end;
|
||||
|
||||
{$IFDEF D2009PLUS}
|
||||
// Для современных версий Delphi используется механизм анонимных функций.
|
||||
TWorkFunction = reference to function (OperType: Integer; AParams: Variant; var AResParams: Variant; wsi: TWaitStatusInterface): Boolean;
|
||||
{$ELSE}
|
||||
// Для старых версий Delphi приходится объявлять отдельно TWorkFunction и TWorkMethod
|
||||
TWorkFunction = function (OperType: Integer; AParams: Variant; var AResParams: Variant; wsi: TWaitStatusInterface): Boolean;
|
||||
TWorkMethod = function (OperType: Integer; AParams: Variant; var AResParams: Variant; wsi: TWaitStatusInterface): Boolean of object;
|
||||
{$ENDIF}
|
||||
|
||||
TWaitForm = class(TForm)
|
||||
Label1: TLabel;
|
||||
labOperationName: TLabel;
|
||||
Label3: TLabel;
|
||||
Label4: TLabel;
|
||||
lbTime: TLabel;
|
||||
Timer1: TTimer;
|
||||
btnStop: TSpeedButton;
|
||||
labWaitStatus: TLabel;
|
||||
ProgressBar1: TProgressBar;
|
||||
procedure FormShow(Sender: TObject);
|
||||
procedure Timer1Timer(Sender: TObject);
|
||||
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
|
||||
procedure btnStopClick(Sender: TObject);
|
||||
private
|
||||
AThread: TThread;
|
||||
FResParams: Variant;
|
||||
FError: string;
|
||||
FIsSuccess: Boolean;
|
||||
FStartTime: TDateTime;
|
||||
FCanClose: Boolean;
|
||||
FStatusInterface: TWaitStatusInterface;
|
||||
public
|
||||
{ Public declarations }
|
||||
end;
|
||||
|
||||
function DoOperationInThread(AOwner: TForm; OperType: Integer; OperationName: string; AParams: Variant;
|
||||
WorkFunc: TWorkFunction; ShowStopButton: Boolean; var AResParams: Variant): Boolean; overload;
|
||||
|
||||
{$IFNDEF D2009PLUS}
|
||||
// Данный вариант используется только для поддержки старых версий Delphi
|
||||
function DoOperationInThread(AOwner: TForm; OperType: Integer; OperationName: string; AParams: Variant;
|
||||
WorkMethod: TWorkMethod; ShowStopButton: Boolean; var AResParams: Variant): Boolean; overload;
|
||||
{$ENDIF}
|
||||
|
||||
implementation
|
||||
|
||||
{$R *.dfm}
|
||||
type
|
||||
TWaitStatusControl = class(TInterfacedObject, TWaitStatusInterface)
|
||||
private
|
||||
FStatusText: TStringList;
|
||||
FOperationName: string;
|
||||
FCritSect: TCriticalSection;
|
||||
FNeedStop: Boolean;
|
||||
FProgressPosition: Integer;
|
||||
FProgressMin: Integer;
|
||||
FProgressMax: Integer;
|
||||
public
|
||||
function GetOperationName: string;
|
||||
procedure SetOperationName(const Value: string);
|
||||
function GetStatusText: string;
|
||||
procedure SetStatusText(const Value: string);
|
||||
function GetNeedStop: Boolean;
|
||||
procedure SetNeedStop(const Value: Boolean);
|
||||
function GetStatusLine(LineNum: Integer): string;
|
||||
procedure SetStatusLine(LineNum: Integer; const Value: string);
|
||||
procedure ClearStatusText;
|
||||
procedure CheckNeedStop;
|
||||
procedure SetProgressPosition(Value: Double);
|
||||
function GetProgressPosition: Double;
|
||||
procedure SetProgressMinMax(AMin, AMax: Double);
|
||||
function GetProgressMin: Integer;
|
||||
function GetProgressMax: Integer;
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
end;
|
||||
|
||||
TBackgroundOperationsThread = class(TThread)
|
||||
public
|
||||
FParams: Variant;
|
||||
FWorkFunc: TWorkFunction;
|
||||
{$IFNDEF D2009PLUS}
|
||||
FWorkMethod: TWorkMethod;
|
||||
{$ENDIF}
|
||||
FForm: TForm;
|
||||
|
||||
// Эвент нужен для того, чтобы доп. поток немедленно отреагирован на отображения
|
||||
// окна ожидания на экране.
|
||||
FEvent: TEvent;
|
||||
FStatusInterface: TWaitStatusInterface;
|
||||
FOperType: Integer;
|
||||
protected
|
||||
procedure Execute; override;
|
||||
public
|
||||
constructor Create(AParams: Variant; AWorkFunc: TWorkFunction; {$IFNDEF D2009PLUS}AWorkMethod: TWorkMethod; {$ENDIF}
|
||||
AForm: TForm; AStatusInterface: TWaitStatusInterface; OperType: Integer);
|
||||
destructor Destroy; override;
|
||||
end;
|
||||
|
||||
function DoOperationInThreadInternal(AOwner: TForm; OperType: Integer; OperationName: string; AParams: Variant;
|
||||
WorkFunc: TWorkFunction; {$IFNDEF D2009PLUS}WorkMethod: TWorkMethod; {$ENDIF}ShowStopButton: Boolean; var AResParams: Variant): Boolean;
|
||||
var
|
||||
AForm: TWaitForm;
|
||||
begin
|
||||
if GetCurrentThreadId <> MainThreadID then
|
||||
raise Exception.Create('DoOperationInThreadInternal: Вызов должен происходить из главного потока');
|
||||
|
||||
AForm := TWaitForm.Create(AOwner);
|
||||
try
|
||||
AForm.btnStop.Visible := ShowStopButton;
|
||||
|
||||
AForm.labOperationName.Caption := OperationName;
|
||||
AForm.labOperationName.Left := (AForm.Width - AForm.labOperationName.Width) div 2;
|
||||
|
||||
AForm.labWaitStatus.Caption := '';
|
||||
|
||||
AForm.FStatusInterface := TWaitStatusControl.Create;
|
||||
|
||||
AForm.AThread := TBackgroundOperationsThread.Create(AParams, WorkFunc, {$IFNDEF D2009PLUS}WorkMethod, {$ENDIF}AForm, AForm.FStatusInterface, OperType);
|
||||
AForm.ShowModal;
|
||||
|
||||
if AForm.FError <> '' then
|
||||
raise Exception.Create(AForm.FError);
|
||||
|
||||
Result := AForm.FIsSuccess;
|
||||
AResParams := AForm.FResParams;
|
||||
finally
|
||||
AForm.AThread.Free;
|
||||
AForm.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
function DoOperationInThread(AOwner: TForm; OperType: Integer; OperationName: string; AParams: Variant;
|
||||
WorkFunc: TWorkFunction; ShowStopButton: Boolean; var AResParams: Variant): Boolean;
|
||||
begin
|
||||
Result := DoOperationInThreadInternal(AOwner, OperType, OperationName, AParams,
|
||||
WorkFunc, {$IFNDEF D2009PLUS}nil, {$ENDIF}ShowStopButton, AResParams);
|
||||
end;
|
||||
|
||||
{$IFNDEF D2009PLUS}
|
||||
function DoOperationInThread(AOwner: TForm; OperType: Integer; OperationName: string; AParams: Variant;
|
||||
WorkMethod: TWorkMethod; ShowStopButton: Boolean; var AResParams: Variant): Boolean; overload;
|
||||
begin
|
||||
Result := DoOperationInThreadInternal(AOwner, OperType, OperationName, AParams,
|
||||
nil, WorkMethod, ShowStopButton, AResParams);
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
{ TBackgroundOperationsThread }
|
||||
|
||||
constructor TBackgroundOperationsThread.Create(AParams: Variant;
|
||||
AWorkFunc: TWorkFunction; {$IFNDEF D2009PLUS}AWorkMethod: TWorkMethod; {$ENDIF}AForm: TForm;
|
||||
AStatusInterface: TWaitStatusInterface; OperType: Integer);
|
||||
const
|
||||
STATE_NONSIGNALED = FALSE;
|
||||
NOT_AUTO_RESET = TRUE;
|
||||
begin
|
||||
inherited Create(False);
|
||||
FParams := AParams;
|
||||
FWorkFunc := AWorkFunc;
|
||||
{$IFNDEF D2009PLUS}
|
||||
FWorkMethod := AWorkMethod;
|
||||
{$ENDIF}
|
||||
FForm := AForm;
|
||||
FEvent := TEvent.Create(nil, NOT_AUTO_RESET, STATE_NONSIGNALED, '', False);
|
||||
FStatusInterface := AStatusInterface;
|
||||
FOperType := OperType;
|
||||
end;
|
||||
|
||||
destructor TBackgroundOperationsThread.Destroy;
|
||||
begin
|
||||
FEvent.SetEvent; // На всякий случай
|
||||
inherited;
|
||||
FEvent.Free;
|
||||
end;
|
||||
|
||||
procedure TBackgroundOperationsThread.Execute;
|
||||
begin
|
||||
try
|
||||
CoInitialize(nil);
|
||||
try
|
||||
if Assigned(FWorkFunc) then
|
||||
TWaitForm(FForm).FIsSuccess := FWorkFunc(FOperType, FParams, TWaitForm(FForm).FResParams, TWaitForm(FForm).FStatusInterface)
|
||||
{$IFNDEF D2009PLUS}
|
||||
else if Assigned(FWorkMethod) then
|
||||
TWaitForm(FForm).FIsSuccess := FWorkMethod(FOperType, FParams, TWaitForm(FForm).FResParams, TWaitForm(FForm).FStatusInterface)
|
||||
{$ENDIF}
|
||||
finally
|
||||
CoUnInitialize();
|
||||
end;
|
||||
|
||||
except
|
||||
on E: Exception do
|
||||
TWaitForm(FForm).FError := 'Ошибка в потоке: ' + E.Message;
|
||||
end;
|
||||
|
||||
// Ожидаем, когда форма появится на экране
|
||||
FEvent.WaitFor(INFINITE);
|
||||
|
||||
// Выставляем форме разрешение за закрытие
|
||||
TWaitForm(FForm).FCanClose := True;
|
||||
|
||||
// Посылаем форме сообщение о закрытии
|
||||
SendMessage(TWaitForm(FForm).Handle, WM_CLOSE, 0, 0);
|
||||
end;
|
||||
|
||||
procedure TWaitForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
|
||||
begin
|
||||
CanClose := FCanClose;
|
||||
end;
|
||||
|
||||
procedure TWaitForm.FormShow(Sender: TObject);
|
||||
begin
|
||||
FStartTime := Now;
|
||||
|
||||
// Сообщаем потоку о появлении формы на экране
|
||||
TBackgroundOperationsThread(AThread).FEvent.SetEvent;
|
||||
end;
|
||||
|
||||
procedure TWaitForm.btnStopClick(Sender: TObject);
|
||||
begin
|
||||
FStatusInterface.NeedStop := True;
|
||||
end;
|
||||
|
||||
procedure TWaitForm.Timer1Timer(Sender: TObject);
|
||||
begin
|
||||
lbTime.Caption := FormatDateTime('nn:ss', Now - FStartTime);
|
||||
if FStatusInterface.OperationName <> '' then
|
||||
labOperationName.Caption := FStatusInterface.OperationName;
|
||||
labOperationName.Left := (Width - labOperationName.Width) div 2;
|
||||
labWaitStatus.Caption := FStatusInterface.StatusText;
|
||||
ProgressBar1.Visible := FStatusInterface.ProgressPosition > 0;
|
||||
ProgressBar1.Min := FStatusInterface.GetProgressMin;
|
||||
ProgressBar1.Max := FStatusInterface.GetProgressMax;
|
||||
ProgressBar1.Position := Round(FStatusInterface.ProgressPosition);
|
||||
end;
|
||||
|
||||
{ TWaitStatusControl }
|
||||
|
||||
procedure TWaitStatusControl.CheckNeedStop;
|
||||
begin
|
||||
if FNeedStop then
|
||||
raise Exception.Create('Пользователь нажал кнопку "Отмена"');
|
||||
end;
|
||||
|
||||
procedure TWaitStatusControl.ClearStatusText;
|
||||
begin
|
||||
SetStatusText('');
|
||||
end;
|
||||
|
||||
constructor TWaitStatusControl.Create;
|
||||
begin
|
||||
inherited;
|
||||
FStatusText := TStringList.Create;
|
||||
FCritSect := TCriticalSection.Create;
|
||||
FProgressMax := 100;
|
||||
end;
|
||||
|
||||
destructor TWaitStatusControl.Destroy;
|
||||
begin
|
||||
FStatusText.Free;
|
||||
FCritSect.Free;
|
||||
inherited;
|
||||
end;
|
||||
|
||||
function TWaitStatusControl.GetNeedStop: Boolean;
|
||||
begin
|
||||
Result := FNeedStop;
|
||||
end;
|
||||
|
||||
function TWaitStatusControl.GetOperationName: string;
|
||||
begin
|
||||
FCritSect.Enter;
|
||||
Result := FOperationName;
|
||||
FCritSect.Leave;
|
||||
end;
|
||||
|
||||
function TWaitStatusControl.GetProgressMax: Integer;
|
||||
begin
|
||||
Result := FProgressMax;
|
||||
end;
|
||||
|
||||
function TWaitStatusControl.GetProgressMin: Integer;
|
||||
begin
|
||||
Result := FProgressMin;
|
||||
end;
|
||||
|
||||
function TWaitStatusControl.GetProgressPosition: Double;
|
||||
begin
|
||||
Result := FProgressPosition;
|
||||
end;
|
||||
|
||||
function TWaitStatusControl.GetStatusLine(LineNum: Integer): string;
|
||||
begin
|
||||
Result := '';
|
||||
if (LineNum < 1) or (LineNum > 4) then Exit;
|
||||
|
||||
FCritSect.Enter;
|
||||
try
|
||||
if FStatusText.Count < LineNum then Exit;
|
||||
Result := FStatusText[LineNum - 1];
|
||||
finally
|
||||
FCritSect.Leave;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TWaitStatusControl.GetStatusText: string;
|
||||
begin
|
||||
FCritSect.Enter;
|
||||
Result := FStatusText.Text;
|
||||
FCritSect.Leave;
|
||||
end;
|
||||
|
||||
procedure TWaitStatusControl.SetNeedStop(const Value: Boolean);
|
||||
begin
|
||||
FNeedStop := Value;
|
||||
end;
|
||||
|
||||
procedure TWaitStatusControl.SetOperationName(const Value: string);
|
||||
begin
|
||||
FCritSect.Enter;
|
||||
FOperationName := Value;
|
||||
FCritSect.Leave;
|
||||
end;
|
||||
|
||||
procedure TWaitStatusControl.SetProgressMinMax(AMin, AMax: Double);
|
||||
begin
|
||||
FProgressMin := Round(AMin);
|
||||
FProgressMax := Round(AMax);
|
||||
end;
|
||||
|
||||
procedure TWaitStatusControl.SetProgressPosition(Value: Double);
|
||||
begin
|
||||
FProgressPosition := Round(Value);
|
||||
end;
|
||||
|
||||
procedure TWaitStatusControl.SetStatusLine(LineNum: Integer;
|
||||
const Value: string);
|
||||
begin
|
||||
if (LineNum < 1) or (LineNum > 4) then Exit;
|
||||
|
||||
FCritSect.Enter;
|
||||
try
|
||||
while FStatusText.Count < LineNum do
|
||||
FStatusText.Add('');
|
||||
FStatusText[LineNum - 1] := Value;
|
||||
finally
|
||||
FCritSect.Leave;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TWaitStatusControl.SetStatusText(const Value: string);
|
||||
begin
|
||||
FCritSect.Enter;
|
||||
FStatusText.Text := Value;
|
||||
FCritSect.Leave;
|
||||
end;
|
||||
|
||||
end.
|
16
ExWaitWindow/WaitWindowEx.dpr
Normal file
16
ExWaitWindow/WaitWindowEx.dpr
Normal file
@ -0,0 +1,16 @@
|
||||
program WaitWindowEx;
|
||||
|
||||
uses
|
||||
Forms,
|
||||
MainFrm in 'MainFrm.pas' {MainForm},
|
||||
WaitFrm in 'WaitFrm.pas' {WaitForm},
|
||||
TimeIntervals in '..\CommonUtils\TimeIntervals.pas';
|
||||
|
||||
{$R *.res}
|
||||
|
||||
begin
|
||||
Application.Initialize;
|
||||
Application.MainFormOnTaskbar := True;
|
||||
Application.CreateForm(TMainForm, MainForm);
|
||||
Application.Run;
|
||||
end.
|
40
ExWaitWindow/WaitWindowEx.dproj
Normal file
40
ExWaitWindow/WaitWindowEx.dproj
Normal file
@ -0,0 +1,40 @@
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<ProjectGuid>{ec9046a0-8814-4b41-9c07-4315c8b50e49}</ProjectGuid>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>
|
||||
<DCC_DependencyCheckOutputName>WaitWindowEx.exe</DCC_DependencyCheckOutputName>
|
||||
<MainSource>WaitWindowEx.dpr</MainSource>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<Version>7.0</Version>
|
||||
<DCC_DebugInformation>False</DCC_DebugInformation>
|
||||
<DCC_LocalDebugSymbols>False</DCC_LocalDebugSymbols>
|
||||
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
|
||||
<DCC_Define>RELEASE</DCC_Define>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<Version>7.0</Version>
|
||||
<DCC_Define>DEBUG</DCC_Define>
|
||||
</PropertyGroup>
|
||||
<ProjectExtensions>
|
||||
<Borland.Personality>Delphi.Personality</Borland.Personality>
|
||||
<Borland.ProjectType />
|
||||
<BorlandProject>
|
||||
<BorlandProject><Delphi.Personality><Parameters><Parameters Name="UseLauncher">False</Parameters><Parameters Name="LoadAllSymbols">True</Parameters><Parameters Name="LoadUnspecifiedSymbols">False</Parameters></Parameters><VersionInfo><VersionInfo Name="IncludeVerInfo">False</VersionInfo><VersionInfo Name="AutoIncBuild">False</VersionInfo><VersionInfo Name="MajorVer">1</VersionInfo><VersionInfo Name="MinorVer">0</VersionInfo><VersionInfo Name="Release">0</VersionInfo><VersionInfo Name="Build">0</VersionInfo><VersionInfo Name="Debug">False</VersionInfo><VersionInfo Name="PreRelease">False</VersionInfo><VersionInfo Name="Special">False</VersionInfo><VersionInfo Name="Private">False</VersionInfo><VersionInfo Name="DLL">False</VersionInfo><VersionInfo Name="Locale">1049</VersionInfo><VersionInfo Name="CodePage">1251</VersionInfo></VersionInfo><VersionInfoKeys><VersionInfoKeys Name="CompanyName"></VersionInfoKeys><VersionInfoKeys Name="FileDescription"></VersionInfoKeys><VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys><VersionInfoKeys Name="InternalName"></VersionInfoKeys><VersionInfoKeys Name="LegalCopyright"></VersionInfoKeys><VersionInfoKeys Name="LegalTrademarks"></VersionInfoKeys><VersionInfoKeys Name="OriginalFilename"></VersionInfoKeys><VersionInfoKeys Name="ProductName"></VersionInfoKeys><VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys><VersionInfoKeys Name="Comments"></VersionInfoKeys></VersionInfoKeys><Source><Source Name="MainSource">WaitWindowEx.dpr</Source></Source></Delphi.Personality></BorlandProject></BorlandProject>
|
||||
</ProjectExtensions>
|
||||
<Import Project="$(MSBuildBinPath)\Borland.Delphi.Targets" />
|
||||
<ItemGroup>
|
||||
<DelphiCompile Include="WaitWindowEx.dpr">
|
||||
<MainSource>MainSource</MainSource>
|
||||
</DelphiCompile>
|
||||
<DCCReference Include="..\CommonUtils\TimeIntervals.pas" />
|
||||
<DCCReference Include="MainFrm.pas">
|
||||
<Form>MainForm</Form>
|
||||
</DCCReference>
|
||||
<DCCReference Include="WaitFrm.pas">
|
||||
<Form>WaitForm</Form>
|
||||
</DCCReference>
|
||||
</ItemGroup>
|
||||
</Project>
|
BIN
ExWaitWindow/WaitWindowEx.res
Normal file
BIN
ExWaitWindow/WaitWindowEx.res
Normal file
Binary file not shown.
@ -21,8 +21,6 @@ markdown-редакторы не подошли, т.к. они либо не у
|
||||
- пример программирования в PPL. Нужно дать ссылки на статьи и видеоуроки в интернете
|
||||
- подробнее об OmniThreadLibrary - сначала нужно дождаться кроссплатформенной версии
|
||||
- функция SignalObjectAndWait
|
||||
- рассмотреть проблему прерывания ожидания при использования TIdTCPServer (например, при ReadTimeOut равном 30 сек.). Хотелось бы, чтобы и нагрузка на процессор была минимальной и чтобы служба с 1000 подключений могла закрываться оперативно
|
||||
|
||||
|
||||
2020-07-28 - начало работы над markdown-версией
|
||||
-->
|
||||
@ -2597,17 +2595,17 @@ end;
|
||||
3. Использование функции WinAPI-функции `Sleep` либо `WaitForXXX` для организации задержек в бесконечном цикле. Очень простое решение - реализовать в дополнительном потоке бесконечный цикл, периодически проверять значение какого-то флага (либо элемента в очереди), в зависимости от значения флага выполнять какое-либо действие, после чего переводить поток в спящий режим с помощью `Sleep` либо `WaitForXXX`. Если вы укажете время ожидания 1000 мс (или больше), то нет проблем (в том смысле, что нагрузка на процессор будет минимальной - примерно 50000 тактов в секунду при паузе в 1 секунду). Однако если Вы будете проверять значение флага каждые 10 миллисекунд, то нагрузка на процессор будет уже существенной - 2500000 тактов в секунду будет тратиться только на работу `Sleep(10)`. Если у вас запущено 1000 таких потоков и каждый расходует 2500000 тактов в секунду, то будет обеспечена 100% загрузка одного ядра процессора (либо эта загрузка будет размазана по нескольким ядрам). Т.е. ваши 1000 потоков ещё не делают ничего полезного, но уже грузят процессор по полной программе! :)
|
||||
Для того, чтобы такой проблемы не было, не рекомендуется использовать `Sleep` либо `WaitForXXX` с маленькой задержкой. Гораздо лучше использовать `WaitForXXX` с большой задержкой (в том числе, INFINITY), а при изменении значения флага следует переводить объект ядра, который ожидает функция `WaitForXXX`, в сигнальное состояние. В этом случае потоки не будут тратить на контроль состояния флага практически никаких ресурсов процессора!
|
||||
|
||||
4. Неправильное использование компонента `TIdTCPServer`. При разработке TCP-серверов Delphi-программисты чаще всего используют компонет TIdTCPServer. При правильном использовании данный компонент может держать до 50000 подключений (существуют реальные примеры с таким количеством подключений). Разумеется, для этого программа должна быть 64-битной. Для поддержки 50000 подключений будет создано 50000 потоков и выделено около 3 ГБ ОЗУ, что весьма затратно. При таком количестве потоков ни в коем случае не должно быть циклов, в которых выполняется проверка чего-либо каждые 10 мс. Значение `Socket.ReadTimeout` должно быть не менее 10000 (10 секунд). При использовании `Socket.CheckForDataOnSource` для ожидания приёма данных от клиента также желательно использовать значение не менее 10000.
|
||||
**Внимание!** Перед каждым вызовом `Socket.CheckForDataOnSource` необходима проверка `if Socket.InputBuffer.Size = 0 then`, что обусловлено особенностями реализации метода `CheckForDataOnSource`. Если в буфере есть данные, то выполнять вызов `Socket.CheckForDataOnSource` не следует!
|
||||
4. Неправильное использование компонента `TIdTCPServer`. При разработке TCP-серверов Delphi-программисты чаще всего используют компонент TIdTCPServer. При правильном использовании данный компонент может держать до 50000 подключений (существуют реальные примеры с таким количеством подключений). Разумеется, для этого программа должна быть 64-битной. Для поддержки 50000 подключений будет создано 50000 потоков и выделено около 3 ГБ ОЗУ, что весьма затратно. При таком количестве потоков ни в коем случае не должно быть циклов, в которых выполняется проверка чего-либо каждые 10 мс. Значение `Socket.ReadTimeout` должно быть не менее 10000 (10 секунд). При использовании `Socket.CheckForDataOnSource` для ожидания приёма данных от клиента также желательно использовать значение не менее 10000.
|
||||
:warning: **Внимание!** Перед каждым вызовом `Socket.CheckForDataOnSource` необходима проверка `if Socket.InputBuffer.Size = 0 then`, что обусловлено особенностями реализации метода `CheckForDataOnSource`. Если в буфере есть данные, то выполнять вызов `Socket.CheckForDataOnSource` не следует!
|
||||
|
||||
**Информация!** Сами по себе данные в буфере `Socket.InputBuffer` появиться не могут. Появляются они там в следующих случаях:
|
||||
:information_source: **Информация!** Сами по себе данные в буфере `Socket.InputBuffer` появиться не могут. Появляются они там в следующих случаях:
|
||||
а) в контексте вызова метода `Socket.ReadXXX`,
|
||||
б) в контексте вызова метода `Socket.CheckForDataOnSource`,
|
||||
в) в момент подключения клиента к серверу, если клиент сразу же передал данные на сервер.
|
||||
|
||||
**Информация!** На практике Delphi-программисту очень редко приходится разрабатывать TCP-сервер, способный держать 50000 соединений. Всё зависит от того, что именно делает TCP-сервер. Если он не выполняет какой-то особой обработки, а просто возвращает в ответ на запрос клиента текущее время (или иную информацию, которую не нужно запрашивать из базы данных или получать в результате сложных вычислений), то проблем никаких нет. Однако, если на каждый запрос приходится выполнять обращение к базе данных или производить сложные вычисления, то ресурсы сервера могут закончиться гораздо раньше (например, на 1000 соединений). В связи с этим рекомендую минимизировать количество обращений к базе данных и стараться держать всю необходимую информацию в памяти TCP-сервера, периодически обновляя её в фоновом потоке.
|
||||
:information_source: **Информация!** На практике Delphi-программисту очень редко приходится разрабатывать TCP-сервер, способный держать 50000 соединений. Всё зависит от того, что именно делает TCP-сервер. Если он не выполняет какой-то особой обработки, а просто возвращает в ответ на запрос клиента текущее время (или иную информацию, которую не нужно запрашивать из базы данных или получать в результате сложных вычислений), то проблем никаких нет. Однако, если на каждый запрос приходится выполнять обращение к базе данных или производить сложные вычисления, то ресурсы сервера могут закончиться гораздо раньше (например, на 1000 соединений). В связи с этим рекомендую минимизировать количество обращений к базе данных и стараться держать всю необходимую информацию в памяти TCP-сервера, периодически обновляя её в фоновом потоке.
|
||||
|
||||
**Внимание!** Не рекомендую использовать `TIdTCPServer` для решения задачи транзита данных. Данная задача отличается тем, что TCP-сервер не выполняет практически никакой обработки данных, а лишь передаёт клиенту "Б" данные, принятые от клиента "А" (и обратно). Если таких клиентов ("А" и "Б") будет 50000, то программа будет использовать около 3 ГБ ОЗУ. Загрузка процессора при активном обмене данными между клиентами будет также весьма приличной, поскольку при большом количестве потоков будет происходить очень много переключений контекста, а каждое переключение мы оцениваем в 50000 тактов. Существуют гораздо более удачные варианты решения задачи транзита данных: асинхронные сокеты и порты завершения ввода/вывода. И в том и в другом способе используется фиксированное количество потоков (например, 8 потоков для 4-ядерного процессора) и требуется намного меньше ОЗУ (как минимум, в 10 раз меньше, чем при использовании `TIdTCPServer`). Количество переключений контекста также намного меньше (сравнение имеет смысл производить только при высокой интенсивности обмена данными), т.к. за один квант времени поток сможет обработать данные, принятые от нескольких клиентов и передать данные нескольким клиентам.
|
||||
:warning: **Внимание!** Не рекомендую использовать `TIdTCPServer` для решения задачи транзита данных. Данная задача отличается тем, что TCP-сервер не выполняет практически никакой обработки данных, а лишь передаёт клиенту "Б" данные, принятые от клиента "А" (и обратно). Если таких клиентов ("А" и "Б") будет 50000, то программа будет использовать около 3 ГБ ОЗУ. Загрузка процессора при активном обмене данными между клиентами будет также весьма приличной, поскольку при большом количестве потоков будет происходить очень много переключений контекста, а каждое переключение мы оцениваем в 50000 тактов. Существуют гораздо более удачные варианты решения задачи транзита данных: асинхронные сокеты и порты завершения ввода/вывода. И в том и в другом способе используется фиксированное количество потоков (например, 8 потоков для 4-ядерного процессора) и требуется намного меньше ОЗУ (как минимум, в 10 раз меньше, чем при использовании `TIdTCPServer`). Количество переключений контекста также намного меньше (сравнение имеет смысл производить только при высокой интенсивности обмена данными), т.к. за один квант времени каждый поток может обработать множество соединений.
|
||||
|
||||
5. Большой расход памяти при использовании некоторых менеджеров памяти. Современные высокопроизводительные менеджеры памяти, например, [tcmalloc](https://github.com/google/tcmalloc), могут создавать для каждого потока свой собственный пул блоков памяти. Благодаря этому удаётся минимизировать количество блокировок при выделении и освобождении памяти, что позволяет разрабатывать приложения, которые хорошо масштабируются по количеству ядер, т.е. могут максимально эффективно использовать доступные ресурсы памяти и процессора. Кстати, для Delphi имеется интерфейсный файл [tcmalloc.pas](https://github.com/obones/tcmalloc-delphi), позволяющий использовать менеджер памяти tcmalloc, представленный в виде библиотеки "libtcmalloc.dll". С точки зрения производительности, он значительно эффективнее встроенного в Delphi менеждера памяти, при этом поддерживаются любые версии Delphi, однако в нём отсутствуют многие плюшки, которые есть в FastMM4.
|
||||
Проблема таких менеджеров памяти заключается в том, что им требуется значительно больший объем памяти ОЗУ по сравнению со стандартным менеджером памяти. На каждый поток такой менеджер памяти запросто может выделить дополнительно по 1 МБ ОЗУ. При использовании такого менеджера памяти вы не сможете создавать тысячи потоков, поскольку память ОЗУ может очень быстро закончиться. С точки зрения разработки серверов это означает, что сетевую библиотеку Indy10 с таким менеджером памяти лучше не использовать. Вместо Indy10 вы можете рассмотреть сетевые библиотеки, работающие по другим принципам, например, использующие асинхронные сокеты Windows (это сложнее, чем Indy10) либо механизм "i/o completion ports" (это значительно сложнее, чем Indy10).
|
||||
|
Loading…
x
Reference in New Issue
Block a user